From 465e09fc8229a6e8067c787bf04907600dfa279a Mon Sep 17 00:00:00 2001 From: Jarno Date: Thu, 6 Aug 2026 17:22:57 +0300 Subject: [PATCH] Prediction and model training work --- config/train_config.json | 23 ++ notebooks/alpaca.ipynb | 164 ++++++++++ notebooks/bot-prototype.ipynb | 308 +++++++++++++++++++ notebooks/ibkr_scratch.ipynb | 161 ++++++++-- notebooks/models/spy_xgb_v1.json | 2 +- notebooks/models/spy_xgb_v1_meta.json | 4 +- notebooks/spy_direction_dataset.ipynb | 302 +++++++++--------- notebooks/train-xboost.ipynb | 336 +++++++++++++++++++++ src/trading_bot/data/alpaca_daily_lib.py | 255 ++++++++++++++++ src/trading_bot/data/fetch_alpaca_daily.py | 250 ++------------- src/trading_bot/data/train_pipeline.py | 207 +++++++++++++ src/trading_bot/models/prediction.py | 16 + tests/test_prediction.py | 64 ++++ 13 files changed, 1689 insertions(+), 403 deletions(-) create mode 100644 config/train_config.json create mode 100644 src/trading_bot/data/alpaca_daily_lib.py create mode 100644 src/trading_bot/data/train_pipeline.py diff --git a/config/train_config.json b/config/train_config.json new file mode 100644 index 0000000..116210a --- /dev/null +++ b/config/train_config.json @@ -0,0 +1,23 @@ +{ + "symbols": { + "SPY": "SPY", + "VIX": "VIXY", + "TLT": "TLT", + "USO": "USO" + }, + "fractions": { + "train": 0.7, + "validation": 0.15, + "test": 0.15 + }, + "model": { + "n_estimators": 300, + "max_depth": 1, + "learning_rate": 0.01, + "subsample": 0.7, + "colsample_bytree": 0.7, + "early_stopping_rounds": 20, + "random_state": 42, + "eval_metric": "logloss" + } +} diff --git a/notebooks/alpaca.ipynb b/notebooks/alpaca.ipynb index e69de29..d6c89e0 100644 --- a/notebooks/alpaca.ipynb +++ b/notebooks/alpaca.ipynb @@ -0,0 +1,164 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 11, + "id": "c8a08105", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from dotenv import load_dotenv\n", + "from alpaca.trading.client import TradingClient\n", + "\n", + "load_dotenv()\n", + "\n", + "# Set paper=True for paper trading (sandbox), paper=False for live trading\n", + "trading_client = TradingClient(\n", + " api_key=os.getenv(\"ALPACA_API_KEY\"),\n", + " secret_key=os.getenv(\"ALPACA_SECRET_KEY\"),\n", + " paper=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "49b14380", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No open positions.\n" + ] + } + ], + "source": [ + "positions = trading_client.get_all_positions()\n", + "\n", + "if not positions:\n", + " print(\"No open positions.\")\n", + "else:\n", + " print(\"Current Portfolio Positions:\")\n", + " for pos in positions:\n", + " print(\n", + " f\"Symbol: {pos.symbol:<5} | \"\n", + " f\"Qty: {pos.qty:<5} | \"\n", + " f\"Avg Entry Price: ${float(pos.avg_entry_price):.2f} | \"\n", + " f\"Current Price: ${float(pos.current_price):.2f} | \"\n", + " f\"Unrealized P/L: ${float(pos.unrealized_pl):.2f}\"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c032239c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "99997.95 99997.95\n" + ] + } + ], + "source": [ + "account = trading_client.get_account()\n", + "print(\n", + " account.cash,\n", + " account.equity\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "c759e40f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No open orders found.\n" + ] + } + ], + "source": [ + "from alpaca.trading.requests import GetOrdersRequest\n", + "from alpaca.trading.enums import QueryOrderStatus\n", + "\n", + "# Request only open orders\n", + "request_params = GetOrdersRequest(status=QueryOrderStatus.OPEN)\n", + "open_orders = trading_client.get_orders(filter=request_params)\n", + "\n", + "if not open_orders:\n", + " print(\"No open orders found.\")\n", + "else:\n", + " print(f\"Found {len(open_orders)} open order(s):\")\n", + " for order in open_orders:\n", + " print(\n", + " f\"ID: {order.id} | Symbol: {order.symbol} | \"\n", + " f\"Side: {order.side} | Qty: {order.qty} | Status: {order.status}\"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "091cf061", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Submitted Order ID: 4838c16d-7a12-4dc3-80cb-7c5d1dbecda3 | Status: OrderStatus.ACCEPTED\n" + ] + } + ], + "source": [ + "from alpaca.trading.requests import MarketOrderRequest\n", + "from alpaca.trading.enums import OrderSide, TimeInForce\n", + "\n", + "# Define a market buy order for 10 shares of SPY\n", + "market_order_data = MarketOrderRequest(\n", + " symbol=\"SPY\",\n", + " notional=100.0,\n", + " side=OrderSide.BUY,\n", + " time_in_force=TimeInForce.DAY,\n", + ")\n", + "\n", + "# Submit the order\n", + "order = trading_client.submit_order(order_data=market_order_data)\n", + "\n", + "print(f\"Submitted Order ID: {order.id} | Status: {order.status}\")" + ] + } + ], + "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 +} diff --git a/notebooks/bot-prototype.ipynb b/notebooks/bot-prototype.ipynb index e69de29..c5a1429 100644 --- a/notebooks/bot-prototype.ipynb +++ b/notebooks/bot-prototype.ipynb @@ -0,0 +1,308 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "038bf2ce", + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "from pathlib import Path\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "# Source of truth for model inputs (must match training order exactly)\n", + "FEATURE_COLUMNS = [\n", + " \"SPY_ret_5\",\n", + " \"SPY_ret_20\",\n", + " \"SPY_dist_sma50\",\n", + " \"VIX_change_5\",\n", + " \"VIX_rank_20\",\n", + " \"TLT_ret_10\",\n", + " \"USO_ret_5\",\n", + " \"SPY_TLT_ratio_ret\",\n", + "]\n", + "\n", + "DEFAULT_SYMBOLS = {\n", + " \"SPY\": \"SPY\",\n", + " \"VIXY\": \"VIX\", # Change to \"VIX\": \"VIX\" if using raw VIX Parquet\n", + " \"TLT\": \"TLT\",\n", + " \"USO\": \"USO\",\n", + "}\n", + "\n", + "\n", + "def load_raw_close_prices(\n", + " raw_data_dir: Path, symbols: dict[str, str]\n", + ") -> pd.DataFrame:\n", + " \"\"\"Reads raw Parquet files and merges close prices into a single inner-joined DataFrame.\"\"\"\n", + " frames = []\n", + " for symbol, alias in symbols.items():\n", + " path = raw_data_dir / f\"{symbol}.parquet\"\n", + " if not path.exists():\n", + " raise FileNotFoundError(f\"Missing raw data file: {path}\")\n", + "\n", + " frame = pd.read_parquet(path)\n", + " if \"date\" in frame.columns:\n", + " frame = frame.set_index(\"date\")\n", + "\n", + " frame.index = pd.to_datetime(frame.index)\n", + " frame = frame.sort_index()\n", + " frames.append(frame[[\"close\"]].rename(columns={\"close\": f\"{alias}_close\"}))\n", + "\n", + " return pd.concat(frames, axis=1, join=\"inner\")\n", + "\n", + "\n", + "def compute_features(prices: pd.DataFrame) -> pd.DataFrame:\n", + " \"\"\"Computes engineered features from raw merged price history.\"\"\"\n", + " df = prices.copy()\n", + "\n", + " # Target asset features\n", + " df[\"SPY_ret_5\"] = df[\"SPY_close\"].pct_change(5)\n", + " df[\"SPY_ret_20\"] = df[\"SPY_close\"].pct_change(20)\n", + "\n", + " sma_50 = df[\"SPY_close\"].rolling(50).mean()\n", + " df[\"SPY_dist_sma50\"] = (df[\"SPY_close\"] - sma_50) / sma_50\n", + "\n", + " # Volatility / Market Stress\n", + " df[\"VIX_change_5\"] = df[\"VIX_close\"].pct_change(5)\n", + " df[\"VIX_rank_20\"] = df[\"VIX_close\"].rolling(20).rank(pct=True)\n", + "\n", + " # Macro & Relative ratios\n", + " df[\"TLT_ret_10\"] = df[\"TLT_close\"].pct_change(10)\n", + " df[\"USO_ret_5\"] = df[\"USO_close\"].pct_change(5)\n", + " df[\"SPY_TLT_ratio_ret\"] = (df[\"SPY_close\"] / df[\"TLT_close\"]).pct_change(5)\n", + "\n", + " return df[FEATURE_COLUMNS]\n", + "\n", + "\n", + "def get_latest_inference_features(\n", + " raw_data_dir: Path,\n", + " symbols: dict[str, str] | None = None,\n", + " max_age_days: int = 1,\n", + ") -> pd.DataFrame:\n", + " \"\"\"Loads raw prices, computes features, verifies date freshness,\n", + "\n", + " and returns the latest single row for model prediction.\n", + " \"\"\"\n", + " symbols = symbols or DEFAULT_SYMBOLS\n", + "\n", + " # 1. Load prices & compute rolling features\n", + " prices = load_raw_close_prices(raw_data_dir, symbols)\n", + " features = compute_features(prices).dropna()\n", + "\n", + " if features.empty:\n", + " raise ValueError(\n", + " \"Not enough historical rows to compute 50-day rolling window features.\"\n", + " )\n", + "\n", + " # 2. Extract latest available row as a 1-row DataFrame\n", + " latest_row = features.iloc[[-1]]\n", + " latest_date = latest_row.index[0]\n", + "\n", + " # 3. Check data freshness and raise a warning if stale\n", + " now = pd.Timestamp.now()\n", + " latest_date_naive = (\n", + " latest_date.tz_localize(None)\n", + " if latest_date.tz is not None\n", + " else latest_date\n", + " )\n", + " days_old = (now.floor(\"D\") - latest_date_naive.floor(\"D\")).days\n", + "\n", + " if days_old > max_age_days:\n", + " warnings.warn(\n", + " f\"STALE DATA WARNING: Latest feature row is from {latest_date.strftime('%Y-%m-%d')} \"\n", + " f\"({days_old} day(s) old). Update raw Parquet files before executing trades.\",\n", + " UserWarning,\n", + " stacklevel=2,\n", + " )\n", + "\n", + " return latest_row\n", + "\n", + "def get_target_exposure(\n", + " p_pred: float, p_base: float, sensitivity: float = 5.0\n", + ") -> float:\n", + " \"\"\"Maps predicted probability to a target portfolio equity allocation (0.0 to 1.0).\n", + "\n", + " - p_pred == p_base --> 50% Target Exposure (Neutral)\n", + " - p_pred > p_base --> Scale up toward 100% (Bullish)\n", + " - p_pred < p_base --> Scale down toward 0% (Bearish / Cash)\n", + " \"\"\"\n", + " # Calculate deviation from the historical average\n", + " delta = p_pred - p_base\n", + "\n", + " # Base target allocation is 50% equity / 50% cash\n", + " base_allocation = 0.50\n", + "\n", + " # Sensitivity controls how aggressively probability changes alter allocation\n", + " # e.g., a +0.08 delta * 5.0 = +0.40 -> 90% Equity Allocation\n", + " target_allocation = base_allocation + (delta * sensitivity)\n", + "\n", + " # Clamp bounds strictly between 0% (full cash) and 100% (full SPY)\n", + " return float(np.clip(target_allocation, 0.0, 1.0))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b3d2c25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Date: 2026-07-27 | Prob: 0.5843 | Base: 0.5830\n" + ] + }, + { + "data": { + "text/plain": [ + "0.5064256139268726" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "import xgboost as xgb\n", + "\n", + "# 1. Load model and metadata\n", + "model = xgb.XGBClassifier()\n", + "model.load_model(\"models/spy_xgb_v1.json\")\n", + "\n", + "with open(\"models/spy_xgb_v1_meta.json\", \"r\") as f:\n", + " meta = json.load(f)\n", + "\n", + "# 2. Fetch latest features from raw parquet files\n", + "RAW_DATA_DIR = Path(\"../data/ibkr/daily\")\n", + "X_latest = get_latest_inference_features(RAW_DATA_DIR, max_age_days=1)\n", + "\n", + "# 3. Predict probability\n", + "p_pred = float(model.predict_proba(X_latest[meta[\"feature_cols\"]])[0, 1])\n", + "p_base = meta[\"p_base\"]\n", + "\n", + "print(\n", + " f\"Date: {X_latest.index[0].date()} | Prob: {p_pred:.4f} | Base: {p_base:.4f}\"\n", + ")\n", + "\n", + "get_target_exposure(p_pred, p_base, sensitivity=5.0)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3f823fa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SPY_ret_5SPY_ret_20SPY_dist_sma50VIX_change_5VIX_rank_20TLT_ret_10USO_ret_5SPY_TLT_ratio_ret
date
2026-07-27-0.0040430.013855-0.0079380.0070650.75-0.00262-0.005976-0.002378
\n", + "
" + ], + "text/plain": [ + " SPY_ret_5 SPY_ret_20 SPY_dist_sma50 VIX_change_5 VIX_rank_20 \\\n", + "date \n", + "2026-07-27 -0.004043 0.013855 -0.007938 0.007065 0.75 \n", + "\n", + " TLT_ret_10 USO_ret_5 SPY_TLT_ratio_ret \n", + "date \n", + "2026-07-27 -0.00262 -0.005976 -0.002378 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_latest" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "476fd7fd", + "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 +} diff --git a/notebooks/ibkr_scratch.ipynb b/notebooks/ibkr_scratch.ipynb index ec31deb..49af44d 100644 --- a/notebooks/ibkr_scratch.ipynb +++ b/notebooks/ibkr_scratch.ipynb @@ -17,7 +17,26 @@ "execution_count": null, "id": "543426a2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting to IBKR Gateway at 127.0.0.1:4002 with client id 101...\n", + "Failed to connect to IBKR Gateway: This event loop is already running\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Error 200, reqId 9: No security definition has been found for the request, contract: Stock(symbol='VUAA', exchange='SMART', currency='USD')\n", + "Error 200, reqId 10: No security definition has been found for the request\n", + "Canceled order: Trade(contract=Stock(symbol='VUAA', exchange='SMART', currency='USD'), order=MarketOrder(orderId=10, clientId=101, action='BUY', totalQuantity=0.7), orderStatus=OrderStatus(orderId=10, status='Cancelled', filled=0.0, remaining=0.0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[TradeLogEntry(time=datetime.datetime(2026, 7, 30, 19, 36, 57, 539380, tzinfo=datetime.timezone.utc), status='PendingSubmit', message='', errorCode=0), TradeLogEntry(time=datetime.datetime(2026, 7, 30, 19, 36, 57, 743208, tzinfo=datetime.timezone.utc), status='Cancelled', message='Error 200, reqId 10: No security definition has been found for the request', errorCode=200)], advancedError='')\n", + "Peer closed connection.\n" + ] + } + ], "source": [ "import sys\n", "from pathlib import Path\n", @@ -35,36 +54,55 @@ "if str(src_path) not in sys.path:\n", " sys.path.insert(0, str(src_path))\n", "\n", - "from trading_bot.data.fetch_ibkr_daily import (\n", - " IBKR_CLIENT_ID,\n", - " IBKR_CONNECT_TIMEOUT_SECONDS,\n", - " IBKR_HOST,\n", - " IBKR_PORT,\n", - ")\n", + "IBKR_HOST = \"127.0.0.1\"\n", + "IBKR_PORT = 4002\n", + "IBKR_CLIENT_ID = 101\n", + "IBKR_CONNECT_TIMEOUT_SECONDS = 10\n", "\n", "ib = IB()\n", "print(f\"Connecting to IBKR Gateway at {IBKR_HOST}:{IBKR_PORT} with client id {IBKR_CLIENT_ID}...\")\n", - "ib.connect(IBKR_HOST, IBKR_PORT, clientId=IBKR_CLIENT_ID, timeout=IBKR_CONNECT_TIMEOUT_SECONDS)\n", - "print(\"Connection established.\")\n" + "try:\n", + " ib.connect(IBKR_HOST, IBKR_PORT, clientId=IBKR_CLIENT_ID, timeout=IBKR_CONNECT_TIMEOUT_SECONDS)\n", + " print(\"Connection established.\")\n", + "except Exception as e:\n", + " print(f\"Failed to connect to IBKR Gateway: {e}\")\n", + " ib.disconnect()\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "ecdc721f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected: True\n", + "Client ID: 101\n" + ] + } + ], "source": [ "print(f\"Connected: {ib.isConnected()}\")\n", - "print(f\"Client ID: {ib.clientId}\")\n" + "print(f\"Client ID: {ib.client.clientId}\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "10ebc240", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No open portfolio positions were returned.\n" + ] + } + ], "source": [ "portfolio = ib.portfolio()\n", "if not portfolio:\n", @@ -79,27 +117,110 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "id": "fed654ec", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Unknown contract: Stock(symbol='VUAA', exchange='SMART', currency='USD')\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Submitted order for VUAA: Trade(contract=Stock(symbol='VUAA', exchange='SMART', currency='USD'), order=MarketOrder(orderId=10, clientId=101, action='BUY', totalQuantity=0.7), orderStatus=OrderStatus(orderId=10, status='PendingSubmit', filled=0.0, remaining=0.0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[TradeLogEntry(time=datetime.datetime(2026, 7, 30, 19, 36, 57, 539380, tzinfo=datetime.timezone.utc), status='PendingSubmit', message='', errorCode=0)], advancedError='')\n" + ] + } + ], "source": [ "from ib_insync import MarketOrder\n", "\n", - "contract = Stock(\"SPY\", \"SMART\", \"USD\")\n", - "ib.qualifyContracts(contract)\n", + "contract = Stock(\"VUAA\", \"SMART\", \"USD\")\n", + "await ib.qualifyContractsAsync(contract)\n", "\n", "# Adjust the quantity as needed before running this cell.\n", - "order = MarketOrder(\"BUY\", 1)\n", + "order = MarketOrder(\"BUY\", 0.70)\n", "trade = ib.placeOrder(contract, order)\n", "\n", "print(f\"Submitted order for {contract.symbol}: {trade}\")\n" ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "06881101", + "metadata": {}, + "outputs": [], + "source": [ + "trds = ib.trades()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "08663602", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Cancelled', 'Cancelled', 'Cancelled']" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(map(lambda x: x.orderStatus.status, trds))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "2c7abf23", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Trade(contract=Stock(conId=756733, symbol='SPY', right='?', exchange='SMART', currency='USD', localSymbol='SPY', tradingClass='SPY'), order=Order(permId=1578393268, action='BUY', totalQuantity=1.0, orderType='MKT', lmtPrice=0.0, auxPrice=0.0, tif='DAY', ocaType=3, displaySize=2147483647, rule80A='0', openClose='', volatilityType=0, deltaNeutralOrderType='None', referencePriceType=0, account='DUR281921', clearingIntent='IB', cashQty=0.0, dontUseAutoPriceForHedge=True, filledQuantity=0.0, refFuturesConId=2147483647, shareholder='Not an insider or substantial shareholder'), orderStatus=OrderStatus(orderId=0, status='Cancelled', filled=0.0, remaining=0.0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[], advancedError=''),\n", + " Trade(contract=Stock(conId=756733, symbol='SPY', right='?', exchange='SMART', currency='USD', localSymbol='SPY', tradingClass='SPY'), order=Order(permId=24474350, action='BUY', totalQuantity=0.1345, orderType='MKT', lmtPrice=0.0, auxPrice=0.0, tif='DAY', ocaType=3, displaySize=2147483647, rule80A='0', openClose='', volatilityType=0, deltaNeutralOrderType='None', referencePriceType=0, account='DUR281921', clearingIntent='IB', cashQty=0.0, dontUseAutoPriceForHedge=True, filledQuantity=0.0, refFuturesConId=2147483647, shareholder='Not an insider or substantial shareholder'), orderStatus=OrderStatus(orderId=0, status='Cancelled', filled=0.0, remaining=0.0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[], advancedError=''),\n", + " Trade(contract=Stock(symbol='VUAA', exchange='SMART', currency='USD'), order=MarketOrder(orderId=10, clientId=101, action='BUY', totalQuantity=0.7), orderStatus=OrderStatus(orderId=10, status='Cancelled', filled=0.0, remaining=0.0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[TradeLogEntry(time=datetime.datetime(2026, 7, 30, 19, 36, 57, 539380, tzinfo=datetime.timezone.utc), status='PendingSubmit', message='', errorCode=0), TradeLogEntry(time=datetime.datetime(2026, 7, 30, 19, 36, 57, 743208, tzinfo=datetime.timezone.utc), status='Cancelled', message='Error 200, reqId 10: No security definition has been found for the request', errorCode=200)], advancedError='')]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trds" + ] } ], "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "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, diff --git a/notebooks/models/spy_xgb_v1.json b/notebooks/models/spy_xgb_v1.json index cc8ce55..62f03bd 100644 --- a/notebooks/models/spy_xgb_v1.json +++ b/notebooks/models/spy_xgb_v1.json @@ -1 +1 @@ -{"learner":{"attributes":{"best_iteration":"41","best_score":"0.6593948980172475","scikit_learn":"{\"_estimator_type\": \"classifier\"}"},"feature_names":["VIX_rank_20","TLT_ret_10","USO_ret_5","SPY_TLT_ratio_ret","SPY_ret_5","SPY_ret_20","SPY_dist_sma50"],"feature_types":["float","float","float","float","float","float","float"],"gradient_booster":{"model":{"cats":{"enc":[],"feature_segments":[],"sorted_idx":[]},"gbtree_model_param":{"num_parallel_tree":"1","num_trees":"62"},"iteration_indptr":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62],"tree_info":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"trees":[{"base_weights":[1.1503149E-2,3.602216E-4,-1.4237287E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":0,"left_children":[1,-1,-1],"loss_changes":[5.1499934E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.892705E-2,3.602216E-4,-1.4237287E-2],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4388889E2,1.4243056E2,1.4583333E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.2381552E-2,2.2380585E-3,-2.9987623E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":1,"left_children":[1,-1,-1],"loss_changes":[9.187705E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4205446E-2,2.2380585E-3,-2.9987623E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3951015E2,8.603824E1,5.3471912E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.584328E-2,-1.7863275E-3,6.1051417E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":2,"left_children":[1,-1,-1],"loss_changes":[2.0163263E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-1.7863275E-3,6.1051417E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4096178E2,9.2359184E1,4.86026E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.7446564E-2,7.0196665E-3,-1.0298543E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":3,"left_children":[1,-1,-1],"loss_changes":[1.4477959E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7963655E-2,7.0196665E-3,-1.0298543E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4530872E2,2.6470573E1,1.1883814E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.2338286E-3,3.326677E-3,-1.7981239E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":4,"left_children":[1,-1,-1],"loss_changes":[8.945065E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.1166078E-2,3.326677E-3,-1.7981239E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4530305E2,5.2463432E1,9.283963E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.0314475E-2,6.923221E-3,-1.2672357E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":5,"left_children":[1,-1,-1],"loss_changes":[1.0347677E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,6.923221E-3,-1.2672357E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4626752E2,1.648944E1,1.2977808E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.5649436E-2,-3.922325E-3,4.0787407E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":6,"left_children":[1,-1,-1],"loss_changes":[2.3413443E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.8626295E-3,-3.922325E-3,4.0787407E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4458455E2,6.905801E1,7.5526535E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.350957E-2,2.346545E-3,-3.7299043E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":7,"left_children":[1,-1,-1],"loss_changes":[1.3207154E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.2120422E-2,2.346545E-3,-3.7299043E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4311383E2,8.012777E1,6.2986057E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.571592E-2,2.4388554E-3,-3.3179298E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":8,"left_children":[1,-1,-1],"loss_changes":[1.20824E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.0081088E-3,2.4388554E-3,-3.3179298E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4409773E2,6.91606E1,7.493713E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.3208794E-2,5.398977E-3,-1.340681E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":9,"left_children":[1,-1,-1],"loss_changes":[9.853788E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,5.398977E-3,-1.340681E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4532292E2,2.5438362E1,1.1988455E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.1377664E-2,5.879107E-3,-1.8835204E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":10,"left_children":[1,-1,-1],"loss_changes":[1.3957067E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7963655E-2,5.879107E-3,-1.8835204E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4870744E2,2.7587627E1,1.2111981E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-7.708372E-2,-3.119822E-3,3.8407855E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":11,"left_children":[1,-1,-1],"loss_changes":[1.5706812E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.498584E-3,-3.119822E-3,3.8407855E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.428892E2,9.488294E1,4.800626E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.0281362E-2,-2.3203024E-3,5.485706E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":12,"left_children":[1,-1,-1],"loss_changes":[2.1079298E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.3203024E-3,5.485706E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4579202E2,9.1525566E1,5.4266453E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.1625227E-3,-1.9508296E-3,5.1844628E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":13,"left_children":[1,-1,-1],"loss_changes":[1.4816274E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.39965955E-2,-1.9508296E-3,5.1844628E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4216734E2,1.02715324E2,3.945202E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.9994316E-2,1.3782366E-3,-4.2710844E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":14,"left_children":[1,-1,-1],"loss_changes":[1.0079788E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1620143E-2,1.3782366E-3,-4.2710844E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4048087E2,9.420001E1,4.6280857E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.694477E-2,9.638787E-3,-1.386698E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":15,"left_children":[1,-1,-1],"loss_changes":[1.1979356E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.6470924E-2,9.638787E-3,-1.386698E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4098901E2,9.650531E0,1.3133847E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.7866395E-2,7.018735E-3,-4.2132087E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":16,"left_children":[1,-1,-1],"loss_changes":[7.4019384E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.0406374E-2,7.018735E-3,-4.2132087E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3778816E2,1.3979691E1,1.2380847E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.828296E-2,-9.890401E-4,5.622155E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":17,"left_children":[1,-1,-1],"loss_changes":[1.20842285E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.39965955E-2,-9.890401E-4,5.622155E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3928114E2,1.0253473E2,3.674642E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-7.00861E-2,7.609278E-3,-1.4937288E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":18,"left_children":[1,-1,-1],"loss_changes":[9.659922E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.3476964E-2,7.609278E-3,-1.4937288E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4388524E2,1.1783532E1,1.3210172E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.8294593E-2,-3.3800001E-3,3.82496E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":19,"left_children":[1,-1,-1],"loss_changes":[1.8128857E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.5142616E-4,-3.3800001E-3,3.82496E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.404793E2,8.019525E1,6.028404E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.9752125E-2,-4.105855E-3,3.2849042E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":20,"left_children":[1,-1,-1],"loss_changes":[2.0203615E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.69106E-3,-4.105855E-3,3.2849042E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4633846E2,7.684254E1,6.949591E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.387051E-2,-2.2152334E-3,4.9509583E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":21,"left_children":[1,-1,-1],"loss_changes":[1.6893894E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.2152334E-3,4.9509583E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4414725E2,9.513496E1,4.901229E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.9092104E-2,-2.770882E-3,3.818329E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":22,"left_children":[1,-1,-1],"loss_changes":[1.351757E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.046347E-3,-2.770882E-3,3.818329E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3853159E2,9.294873E1,4.5582867E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.2396117E-2,2.268656E-3,-3.1107063E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":23,"left_children":[1,-1,-1],"loss_changes":[9.642728E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1620143E-2,2.268656E-3,-3.1107063E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4580359E2,9.603986E1,4.976373E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.9717136E-4,1.9997586E-3,-4.054914E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":24,"left_children":[1,-1,-1],"loss_changes":[1.1343123E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.3939522E-2,1.9997586E-3,-4.054914E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3806137E2,9.2915596E1,4.5145775E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.8451783E-2,6.0415994E-3,-1.1212268E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":25,"left_children":[1,-1,-1],"loss_changes":[6.9379697E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4933084E-2,6.0415994E-3,-1.1212268E-3],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4411978E2,1.4082354E1,1.3003743E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.7917956E-2,-3.3980121E-3,4.3788254E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":26,"left_children":[1,-1,-1],"loss_changes":[2.1816666E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.8626295E-3,-3.3980121E-3,4.3788254E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4238264E2,6.961766E1,7.276498E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.1219869E-2,2.0441434E-3,-4.1858647E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":27,"left_children":[1,-1,-1],"loss_changes":[1.3026904E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1620143E-2,2.0441434E-3,-4.1858647E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4632487E2,9.6004395E1,5.0320473E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.9416324E-2,-2.740262E-3,3.507794E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":28,"left_children":[1,-1,-1],"loss_changes":[1.406041E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.69106E-3,-2.740262E-3,3.507794E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4208485E2,7.0865746E1,7.121912E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.8356727E-2,-2.8240487E-3,4.358995E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":29,"left_children":[1,-1,-1],"loss_changes":[1.6733116E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.8240487E-3,4.358995E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4555128E2,9.8406715E1,4.714458E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.656652E-3,-2.5718545E-3,5.069005E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":30,"left_children":[1,-1,-1],"loss_changes":[1.8627548E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.5718545E-3,5.069005E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4218597E2,9.552672E1,4.665926E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.9354446E-2,-4.9880473E-3,2.5265855E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":31,"left_children":[1,-1,-1],"loss_changes":[1.9272284E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7582418E-2,-4.9880473E-3,2.5265855E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4361893E2,5.3609554E1,9.000938E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.3786807E-2,8.684349E-3,-5.3198775E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":32,"left_children":[1,-1,-1],"loss_changes":[1.0346715E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.3476964E-2,8.684349E-3,-5.3198775E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4087578E2,1.2448235E1,1.2842754E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.435766E-3,-3.4412364E-3,2.960405E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":33,"left_children":[1,-1,-1],"loss_changes":[1.4951953E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.8626295E-3,-3.4412364E-3,2.960405E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4429129E2,6.85662E1,7.572508E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.3821368E-1,3.4961607E-3,-1.320792E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":34,"left_children":[1,-1,-1],"loss_changes":[7.9995074E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.0374096E-2,3.4961607E-3,-1.320792E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3818887E2,7.737702E1,6.0811855E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.2121364E-1,4.662842E-3,-4.8677507E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":35,"left_children":[1,-1,-1],"loss_changes":[8.640629E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.5531809E-2,4.662842E-3,-4.8677507E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4600238E2,4.7592117E1,9.841026E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.5210026E-2,2.3994036E-3,-3.0564698E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":36,"left_children":[1,-1,-1],"loss_changes":[9.677734E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1620143E-2,2.3994036E-3,-3.0564698E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3957443E2,8.9961006E1,4.961343E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.9298238E-2,1.1189663E-2,-1.9199468E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":37,"left_children":[1,-1,-1],"loss_changes":[7.8486223E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-7.246757E-2,1.1189663E-2,-1.9199468E-4],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.471111E2,5.3279424E0,1.4178316E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.399823E-2,1.8965567E-3,-4.24299E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":38,"left_children":[1,-1,-1],"loss_changes":[1.0593362E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.1135263E-2,1.8965567E-3,-4.24299E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4636862E2,1.0969699E2,3.667164E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.0468457E-2,4.1548056E-3,-1.1793928E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":39,"left_children":[1,-1,-1],"loss_changes":[5.6937346E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,4.1548056E-3,-1.1793928E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3184128E2,2.3494942E1,1.0834634E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.1492526E-2,7.121196E-3,-9.191377E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":40,"left_children":[1,-1,-1],"loss_changes":[8.484619E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,7.121196E-3,-9.191377E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4367465E2,1.3585001E1,1.3008965E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.497916E-2,-9.87152E-4,5.443999E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":41,"left_children":[1,-1,-1],"loss_changes":[1.1573458E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.39965955E-2,-9.87152E-4,5.443999E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4028429E2,1.0297233E2,3.7311962E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.580447E-2,-2.953105E-3,3.7048592E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":42,"left_children":[1,-1,-1],"loss_changes":[1.5747092E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.9884456E-3,-2.953105E-3,3.7048592E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4028432E2,7.269906E1,6.758525E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.087741E-3,7.7399896E-3,-5.671346E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":43,"left_children":[1,-1,-1],"loss_changes":[7.1167145E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.5148077E-2,7.7399896E-3,-5.671346E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3952307E2,1.01991825E1,1.2932388E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.4611776E-2,-2.9304125E-3,4.736233E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":44,"left_children":[1,-1,-1],"loss_changes":[1.7987709E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.9304125E-3,4.736233E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3489554E2,8.970525E1,4.5190285E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.0552E-2,-3.3133684E-3,4.2325873E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":45,"left_children":[1,-1,-1],"loss_changes":[2.0485882E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.8626295E-3,-3.3133684E-3,4.2325873E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.421373E2,6.836182E1,7.377549E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.1084006E-2,-3.758726E-3,2.0739995E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":46,"left_children":[1,-1,-1],"loss_changes":[1.2576108E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.9884456E-3,-3.758726E-3,2.0739995E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4596483E2,7.204372E1,7.392111E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.068163E-1,-5.670291E-3,1.1214392E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":47,"left_children":[1,-1,-1],"loss_changes":[1.51296E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.2980139E-2,-5.670291E-3,1.1214392E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4851141E2,4.736646E1,1.0114495E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.007658E-2,1.7124419E-3,-4.322607E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":48,"left_children":[1,-1,-1],"loss_changes":[1.1659641E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1620143E-2,1.7124419E-3,-4.322607E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3879352E2,9.056025E1,4.823327E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.0701784E-2,-2.7265185E-3,2.7835416E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":49,"left_children":[1,-1,-1],"loss_changes":[1.1334619E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.7703783E-3,-2.7265185E-3,2.7835416E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4769241E2,7.750873E1,7.0183685E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.855976E-4,5.028119E-3,-1.1822984E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":50,"left_children":[1,-1,-1],"loss_changes":[8.798201E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.5336391E-2,5.028119E-3,-1.1822984E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4507086E2,2.7230198E1,1.1784066E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.1468798E-2,-2.037836E-3,4.981943E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":51,"left_children":[1,-1,-1],"loss_changes":[1.3903425E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.39965955E-2,-2.037836E-3,4.981943E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4467838E2,1.07553085E2,3.7125286E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.1599186E-2,1.0753028E-3,-6.1705606E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":52,"left_children":[1,-1,-1],"loss_changes":[7.2637935E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.6045145E-2,1.0753028E-3,-6.1705606E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4513171E2,1.3066982E2,1.4461886E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.9109923E-3,2.0861586E-3,-2.5921254E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":53,"left_children":[1,-1,-1],"loss_changes":[7.888134E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.0972753E-2,2.0861586E-3,-2.5921254E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4338414E2,7.834685E1,6.50373E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.541693E-2,-4.7181547E-3,2.7364993E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":54,"left_children":[1,-1,-1],"loss_changes":[1.907261E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7198509E-2,-4.7181547E-3,2.7364993E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4258781E2,5.5045696E1,8.7542114E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.793089E-2,-4.270684E-3,2.938179E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":55,"left_children":[1,-1,-1],"loss_changes":[1.872198E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.9884456E-3,-4.270684E-3,2.938179E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4214075E2,7.12372E1,7.090354E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.0137361E-1,4.9936835E-4,-5.0488673E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":56,"left_children":[1,-1,-1],"loss_changes":[8.672843E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.0858375E-2,4.9936835E-4,-5.0488673E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4063496E2,1.0291854E2,3.7716427E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.449439E-2,-2.6215576E-3,3.7384462E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":57,"left_children":[1,-1,-1],"loss_changes":[1.3604961E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.0351773E-3,-2.6215576E-3,3.7384462E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4429385E2,9.2872574E1,5.142128E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.209277E-2,-2.1818222E-3,5.118343E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":58,"left_children":[1,-1,-1],"loss_changes":[1.4444012E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.39965955E-2,-2.1818222E-3,5.118343E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3589288E2,9.9823265E1,3.6069614E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.1114854E-2,-2.2430532E-3,3.6860367E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":59,"left_children":[1,-1,-1],"loss_changes":[1.1584419E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.9238376E-3,-2.2430532E-3,3.6860367E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4424765E2,9.509283E1,4.915482E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.2282032E-2,-3.570684E-3,2.7332043E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":60,"left_children":[1,-1,-1],"loss_changes":[1.4923586E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.472012E-3,-3.570684E-3,2.7332043E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4837196E2,7.184672E1,7.6525246E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-9.693615E-3,-2.9389095E-3,3.001408E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":61,"left_children":[1,-1,-1],"loss_changes":[1.2675176E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.9884456E-3,-2.9389095E-3,3.001408E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4194582E2,7.406278E1,6.788303E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}}]},"name":"gbtree"},"learner_model_param":{"base_score":"[5.833333E-1]","boost_from_average":"1","num_class":"0","num_feature":"7","num_target":"1"},"objective":{"name":"binary:logistic","reg_loss_param":{"scale_pos_weight":"1"}}},"version":[3,2,0]} \ No newline at end of file +{"learner":{"attributes":{"best_iteration":"131","best_score":"0.6530751986636056","scikit_learn":"{\"_estimator_type\": \"classifier\"}"},"feature_names":["VIX_rank_20","TLT_ret_10","USO_ret_5","SPY_TLT_ratio_ret","SPY_ret_5","SPY_ret_20","SPY_dist_sma50"],"feature_types":["float","float","float","float","float","float","float"],"gradient_booster":{"model":{"cats":{"enc":[],"feature_segments":[],"sorted_idx":[]},"gbtree_model_param":{"num_parallel_tree":"1","num_trees":"152"},"iteration_indptr":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152],"tree_info":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"trees":[{"base_weights":[9.09237E-3,3.342369E-4,-1.4195536E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":0,"left_children":[1,-1,-1],"loss_changes":[5.105532E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.892705E-2,3.342369E-4,-1.4195536E-2],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4451103E2,1.4305133E2,1.4597074E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.9695353E-2,2.3339752E-3,-3.2156436E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":1,"left_children":[1,-1,-1],"loss_changes":[1.0367284E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4354015E-2,2.3339752E-3,-3.2156436E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4012877E2,8.636299E1,5.376578E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.294399E-2,-1.785295E-3,6.0087293E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":2,"left_children":[1,-1,-1],"loss_changes":[1.9767847E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-1.785295E-3,6.0087293E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4158235E2,9.269047E1,4.8891888E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.908758E-2,7.0679425E-3,-1.0177689E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":3,"left_children":[1,-1,-1],"loss_changes":[1.4627343E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7963655E-2,7.0679425E-3,-1.0177689E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4569156E2,2.6495813E1,1.1919575E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.9804457E-3,3.4415158E-3,-1.9024174E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":4,"left_children":[1,-1,-1],"loss_changes":[9.772864E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.0558252E-2,3.4415158E-3,-1.9024174E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4592857E2,5.2756344E1,9.317223E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.8463421E-2,6.9694594E-3,-1.250735E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":5,"left_children":[1,-1,-1],"loss_changes":[1.0434825E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,6.9694594E-3,-1.250735E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4665097E2,1.6505238E1,1.3014574E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.73039E-2,-3.935056E-3,4.084229E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":6,"left_children":[1,-1,-1],"loss_changes":[2.3570513E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-3.935056E-3,4.084229E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4496594E2,6.888007E1,7.608588E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.5739645E-2,2.3102474E-3,-3.6635168E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":7,"left_children":[1,-1,-1],"loss_changes":[1.28497505E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.1604869E-2,2.3102474E-3,-3.6635168E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4373654E2,7.971627E1,6.402028E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.389124E-2,2.451316E-3,-3.3226286E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":8,"left_children":[1,-1,-1],"loss_changes":[1.2190954E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.261376E-3,2.451316E-3,-3.3226286E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.444779E2,6.971281E1,7.476509E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.1461531E-2,5.4480718E-3,-1.3278441E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":9,"left_children":[1,-1,-1],"loss_changes":[9.973122E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,5.4480718E-3,-1.3278441E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4570404E2,2.5463345E1,1.2024069E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.9494738E-2,5.926848E-3,-1.8687078E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":10,"left_children":[1,-1,-1],"loss_changes":[1.4094485E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7963655E-2,5.926848E-3,-1.8687078E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4909135E2,2.761469E1,1.2147666E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-7.525367E-2,-3.1129941E-3,3.8926841E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":11,"left_children":[1,-1,-1],"loss_changes":[1.593989E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.498584E-3,-3.1129941E-3,3.8926841E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4326752E2,9.52144E1,4.8053112E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.7753846E-2,-2.3183294E-3,5.4065334E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":12,"left_children":[1,-1,-1],"loss_changes":[2.0740154E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.3183294E-3,5.4065334E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4641576E2,9.185297E1,5.4562782E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.712827E-3,-1.6603329E-3,6.022334E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":13,"left_children":[1,-1,-1],"loss_changes":[1.4866889E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8341033E-2,-1.6603329E-3,6.022334E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4254373E2,1.1105156E2,3.1492176E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.844924E-2,1.3258393E-3,-4.1007707E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":14,"left_children":[1,-1,-1],"loss_changes":[9.341028E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,1.3258393E-3,-4.1007707E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4085332E2,9.428634E1,4.656697E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.9228975E-2,5.5880575E-3,-1.9631886E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":15,"left_children":[1,-1,-1],"loss_changes":[1.2192345E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,5.5880575E-3,-1.9631886E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4160788E2,2.514988E1,1.16458E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.4919355E-2,7.222998E-3,-4.903815E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":16,"left_children":[1,-1,-1],"loss_changes":[8.080426E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.999586E-2,7.222998E-3,-4.903815E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.384022E2,1.4237029E1,1.2416517E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.523218E-2,-8.6349744E-4,6.3398E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":17,"left_children":[1,-1,-1],"loss_changes":[1.2775277E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8198002E-2,-8.6349744E-4,6.3398E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3989534E2,1.0917031E2,3.0725039E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.817809E-2,7.6645357E-3,-1.477102E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":18,"left_children":[1,-1,-1],"loss_changes":[9.755897E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.3476964E-2,7.6645357E-3,-1.477102E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4426485E2,1.1799602E1,1.3246524E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.0774696E-2,-3.3847564E-3,3.7693256E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":19,"left_children":[1,-1,-1],"loss_changes":[1.7953756E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.5142616E-4,-3.3847564E-3,3.7693256E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4109569E2,8.050645E1,6.058925E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.4176062E-2,-3.1298671E-3,4.6633873E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":20,"left_children":[1,-1,-1],"loss_changes":[2.001249E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-3.1298671E-3,4.6633873E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4647104E2,9.8094925E1,4.8376114E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.5369989E-2,-2.2090203E-3,4.994746E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":21,"left_children":[1,-1,-1],"loss_changes":[1.7101246E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.2090203E-3,4.994746E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4452158E2,9.54661E1,4.9055477E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.1379366E-2,-2.761151E-3,3.719049E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":22,"left_children":[1,-1,-1],"loss_changes":[1.3142444E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.058913E-3,-2.761151E-3,3.719049E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.391497E2,9.328191E1,4.586779E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.993933E-2,2.0749546E-3,-3.1546624E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":23,"left_children":[1,-1,-1],"loss_changes":[8.844706E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.3916533E-2,2.0749546E-3,-3.1546624E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4642554E2,9.9793846E1,4.6631683E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.4006628E-3,4.201714E-3,-1.9091311E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":24,"left_children":[1,-1,-1],"loss_changes":[1.1206415E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.4326648E-2,4.201714E-3,-1.9091311E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3867091E2,4.2399265E1,9.627165E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.2937597E-2,6.090522E-3,-1.0658515E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":25,"left_children":[1,-1,-1],"loss_changes":[6.9324017E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4933084E-2,6.090522E-3,-1.0658515E-3],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.442484E2,1.4096718E1,1.3015169E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.9250984E-2,-3.355394E-3,4.2991186E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":26,"left_children":[1,-1,-1],"loss_changes":[2.1180513E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-3.355394E-3,4.2991186E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4275575E2,6.91737E1,7.358206E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-9.7437175E-3,2.0009577E-3,-4.0450008E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":27,"left_children":[1,-1,-1],"loss_changes":[1.2315502E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,2.0009577E-3,-4.0450008E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4669716E2,9.6104355E1,5.0592804E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.6796827E-2,-2.6271516E-3,3.3418227E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":28,"left_children":[1,-1,-1],"loss_changes":[1.2887652E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4922787E-3,-2.6271516E-3,3.3418227E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4270479E2,7.115627E1,7.1548515E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.0646E-2,-2.8162897E-3,4.2607253E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":29,"left_children":[1,-1,-1],"loss_changes":[1.6325298E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.8162897E-3,4.2607253E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.461686E2,9.873706E1,4.7431534E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.2924477E-3,-2.567994E-3,5.114523E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":30,"left_children":[1,-1,-1],"loss_changes":[1.8864166E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.567994E-3,5.114523E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4255605E2,9.5851295E1,4.670475E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.1793144E-2,-5.024728E-3,2.5136783E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":31,"left_children":[1,-1,-1],"loss_changes":[1.9483017E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7545339E-2,-5.024728E-3,2.5136783E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4423547E2,5.3887444E1,9.034803E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.1070411E-2,8.739057E-3,-5.6455773E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":32,"left_children":[1,-1,-1],"loss_changes":[1.056113E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.3476964E-2,8.739057E-3,-5.6455773E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4149384E2,1.2466162E1,1.2902768E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.7642127E-3,-3.468882E-3,3.0702378E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":33,"left_children":[1,-1,-1],"loss_changes":[1.560975E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-3.468882E-3,3.0702378E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4442635E2,6.8364624E1,7.606172E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.3481839E-1,2.3285397E-3,-4.131767E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":34,"left_children":[1,-1,-1],"loss_changes":[7.606859E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.4301035E-2,2.3285397E-3,-4.131767E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3880316E2,1.1822749E2,2.057566E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.179654E-1,4.4845594E-3,-5.9949624E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":35,"left_children":[1,-1,-1],"loss_changes":[8.706541E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.331049E-2,4.4845594E-3,-5.9949624E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4661513E2,5.077539E1,9.583973E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.2014286E-2,2.287717E-3,-2.9405733E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":36,"left_children":[1,-1,-1],"loss_changes":[8.928646E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,2.287717E-3,-2.9405733E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4018591E2,9.031596E1,4.9869953E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.6823899E-2,1.1221515E-2,-2.1735625E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":37,"left_children":[1,-1,-1],"loss_changes":[7.935387E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-7.246757E-2,1.1221515E-2,-2.1735625E-4],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4773486E2,5.3329935E0,1.4240187E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.1497244E-2,1.8496556E-3,-4.2272173E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":38,"left_children":[1,-1,-1],"loss_changes":[1.03945265E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.1135263E-2,1.8496556E-3,-4.2272173E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4699312E2,1.10313835E2,3.667928E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.9203221E-2,4.4074706E-3,-1.1203064E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":39,"left_children":[1,-1,-1],"loss_changes":[5.736892E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.8575827E-2,4.4074706E-3,-1.1203064E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3220958E2,2.1572422E1,1.1063715E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.4131938E-2,7.1578496E-3,-9.493848E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":40,"left_children":[1,-1,-1],"loss_changes":[8.637583E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,7.1578496E-3,-9.493848E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4429208E2,1.3598679E1,1.306934E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.599986E-2,-9.429338E-4,5.412254E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":41,"left_children":[1,-1,-1],"loss_changes":[1.1273544E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-9.429338E-4,5.412254E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4065407E2,1.0354816E2,3.7105915E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.718171E-2,-2.9058557E-3,3.5763378E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":42,"left_children":[1,-1,-1],"loss_changes":[1.4979364E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-6.691129E-3,-2.9058557E-3,3.5763378E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4066159E2,7.176858E1,6.889301E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.151618E-3,7.800185E-3,-6.0201157E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":43,"left_children":[1,-1,-1],"loss_changes":[7.294163E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.5148077E-2,7.800185E-3,-6.0201157E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4013841E2,1.0217456E1,1.2992094E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.7777763E-2,-2.9291573E-3,4.6271994E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":44,"left_children":[1,-1,-1],"loss_changes":[1.756646E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.9291573E-3,4.6271994E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3550331E2,9.002576E1,4.547755E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.178782E-2,-3.34114E-3,4.243278E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":45,"left_children":[1,-1,-1],"loss_changes":[2.07404E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-3.34114E-3,4.243278E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4251419E2,6.8160164E1,7.435403E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.3152466E-2,-3.6454378E-3,1.921277E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":46,"left_children":[1,-1,-1],"loss_changes":[1.1502596E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.928212E-3,-3.6454378E-3,1.921277E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4659029E2,7.2330154E1,7.426013E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.0480574E-1,-5.621723E-3,1.1216186E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":47,"left_children":[1,-1,-1],"loss_changes":[1.4938073E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.2805313E-2,-5.621723E-3,1.1216186E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4889883E2,4.7396408E1,1.0150242E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.854579E-2,1.720713E-3,-4.30958E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":48,"left_children":[1,-1,-1],"loss_changes":[1.1659117E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,1.720713E-3,-4.30958E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3917108E2,9.092887E1,4.824221E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.30014885E-2,-2.731608E-3,2.6292624E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":49,"left_children":[1,-1,-1],"loss_changes":[1.0790761E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.028103E-3,-2.731608E-3,2.6292624E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.483197E2,7.6346344E1,7.1973366E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.1814797E-3,5.0536874E-3,-1.2096539E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":50,"left_children":[1,-1,-1],"loss_changes":[8.962622E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.5519591E-2,5.0536874E-3,-1.2096539E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.457039E2,2.7249668E1,1.1845423E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.9996395E-2,-1.9916848E-3,4.959693E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":51,"left_children":[1,-1,-1],"loss_changes":[1.3601212E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.9916848E-3,4.959693E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4505646E2,1.08123825E2,3.6932632E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.8642097E-2,1.0324684E-3,-6.107673E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":52,"left_children":[1,-1,-1],"loss_changes":[7.063298E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.6045145E-2,1.0324684E-3,-6.107673E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4574638E2,1.3126878E2,1.4477595E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.6779794E-3,2.07726E-3,-2.564511E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":53,"left_children":[1,-1,-1],"loss_changes":[7.782566E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.0743914E-2,2.07726E-3,-2.564511E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4375722E2,7.8693596E1,6.506363E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.3580283E-2,-4.666061E-3,2.723838E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":54,"left_children":[1,-1,-1],"loss_changes":[1.8778824E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7545339E-2,-4.666061E-3,2.723838E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4297417E2,5.508172E1,8.7892456E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-7.039246E-2,-4.0620393E-3,2.8878825E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":55,"left_children":[1,-1,-1],"loss_changes":[1.7457226E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4922787E-3,-4.0620393E-3,2.8878825E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4276013E2,7.371258E1,6.9047554E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-9.9985346E-2,4.930476E-4,-5.064932E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":56,"left_children":[1,-1,-1],"loss_changes":[8.643104E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.1135263E-2,4.930476E-4,-5.064932E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.410081E2,1.0377531E2,3.723279E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.3141196E-2,-2.5619152E-3,3.59271E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":57,"left_children":[1,-1,-1],"loss_changes":[1.2842169E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.009951E-3,-2.5619152E-3,3.59271E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4466968E2,9.246114E1,5.2208534E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.5226265E-2,-2.1793337E-3,4.972581E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":58,"left_children":[1,-1,-1],"loss_changes":[1.3953103E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-2.1793337E-3,4.972581E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3650343E2,1.0014865E2,3.6354786E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.3615647E-2,-2.1986596E-3,3.6023783E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":59,"left_children":[1,-1,-1],"loss_changes":[1.1067886E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.1986596E-3,3.6023783E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4487128E2,9.6143715E1,4.872757E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.6467998E-2,-3.538086E-3,2.7325314E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":60,"left_children":[1,-1,-1],"loss_changes":[1.4766515E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.487666E-3,-3.538086E-3,2.7325314E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.48523E2,7.090433E1,7.761866E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.028914E-3,-2.042592E-3,4.3992326E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":61,"left_children":[1,-1,-1],"loss_changes":[1.2688812E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[9.089365E-3,-2.042592E-3,4.3992326E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4232988E2,9.935178E1,4.2978104E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[8.361349E-2,-6.024186E-4,5.8936793E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":62,"left_children":[1,-1,-1],"loss_changes":[1.0666658E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8198002E-2,-6.024186E-4,5.8936793E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4512169E2,1.1367047E2,3.1451218E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.9920037E-2,6.508073E-3,-1.7014855E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":63,"left_children":[1,-1,-1],"loss_changes":[5.5544915E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4933084E-2,6.508073E-3,-1.7014855E-4],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.368263E2,1.2839618E1,1.2398668E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.099373E-2,-1.509226E-3,5.347559E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":64,"left_children":[1,-1,-1],"loss_changes":[1.5011365E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[9.089365E-3,-1.509226E-3,5.347559E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4407558E2,9.790251E1,4.6173077E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.8246409E-2,-2.1898332E-3,5.154719E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":65,"left_children":[1,-1,-1],"loss_changes":[1.5836564E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-2.1898332E-3,5.154719E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4576244E2,1.0635204E2,3.9410385E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.997922E-2,7.801331E-3,-1.0834789E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":66,"left_children":[1,-1,-1],"loss_changes":[6.5709596E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.469514E-2,7.801331E-3,-1.0834789E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4679227E2,1.037679E1,1.3641548E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.1410113E-3,1.7674753E-3,-3.6020707E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":67,"left_children":[1,-1,-1],"loss_changes":[9.235323E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.3916533E-2,1.7674753E-3,-3.6020707E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4620668E2,1.0037971E2,4.5826977E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.5969153E-2,-2.8092694E-3,4.4875247E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":68,"left_children":[1,-1,-1],"loss_changes":[1.73151E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.8092694E-3,4.4875247E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.437664E2,9.578245E1,4.798395E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.895698E-3,4.4299415E-3,-1.245901E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":69,"left_children":[1,-1,-1],"loss_changes":[7.791051E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.2249134E-2,4.4299415E-3,-1.245901E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4329904E2,2.964986E1,1.1364918E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.021408E-2,3.4071824E-3,-6.900492E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":70,"left_children":[1,-1,-1],"loss_changes":[5.5946083E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.4326648E-2,3.4071824E-3,-6.900492E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.469341E2,4.9434647E1,9.749945E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.202676E-2,3.5009496E-3,-1.6464391E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":71,"left_children":[1,-1,-1],"loss_changes":[9.719762E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.950503E-3,3.5009496E-3,-1.6464391E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4486856E2,7.205612E1,7.281245E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.4530764E-3,-2.0067908E-3,3.4657305E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":72,"left_children":[1,-1,-1],"loss_changes":[9.633835E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-2.0067908E-3,3.4657305E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3848845E2,8.961571E1,4.887274E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.5051922E-2,2.1446864E-3,-2.1884553E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":73,"left_children":[1,-1,-1],"loss_changes":[6.680147E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[4.727699E-3,2.1446864E-3,-2.1884553E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4081157E2,6.620098E1,7.461059E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.9229237E-2,1.1366484E-3,-2.9664075E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":74,"left_children":[1,-1,-1],"loss_changes":[5.601711E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.95962E-2,1.1366484E-3,-2.9664075E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4471503E2,9.469091E1,5.002411E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.1253279E-2,-1.8234911E-3,3.969073E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":75,"left_children":[1,-1,-1],"loss_changes":[1.1077597E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-1.8234911E-3,3.969073E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4639754E2,9.781869E1,4.8578846E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.4655763E-2,9.680282E-4,-4.617722E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":76,"left_children":[1,-1,-1],"loss_changes":[8.589052E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.073858E-2,9.680282E-4,-4.617722E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4380797E2,1.0796218E2,3.584578E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[8.0369964E-2,3.6115234E-3,-4.6689238E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":77,"left_children":[1,-1,-1],"loss_changes":[5.1085043E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.659904E-2,3.6115234E-3,-4.6689238E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4171904E2,4.357725E1,9.8141785E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.9010728E-2,6.9223237E-3,-1.1300327E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":78,"left_children":[1,-1,-1],"loss_changes":[6.885842E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.3476964E-2,6.9223237E-3,-1.1300327E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.425176E2,1.0545762E1,1.3197183E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.6728093E-2,-2.2824917E-3,3.376248E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":79,"left_children":[1,-1,-1],"loss_changes":[1.013885E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.498584E-3,-2.2824917E-3,3.376248E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.432175E2,9.755204E1,4.566545E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.1908283E-2,6.8104374E-3,-7.623539E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":80,"left_children":[1,-1,-1],"loss_changes":[3.583129E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-7.246757E-2,6.8104374E-3,-7.623539E-4],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4129079E2,5.550645E0,1.3574014E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.456064E-3,1.2090337E-2,-3.67133E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":81,"left_children":[1,-1,-1],"loss_changes":[5.498081E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.3522766E-2,1.2090337E-2,-3.67133E-4],"split_indices":[4,0,0],"split_type":[0,0,0],"sum_hessian":[1.4266345E2,2.6341538E0,1.400293E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.062618E-3,-2.8950255E-3,1.3508375E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":82,"left_children":[1,-1,-1],"loss_changes":[5.7930546E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.3878913E-2,-2.8950255E-3,1.3508375E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4282524E2,4.7130367E1,9.569488E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.852173E-3,6.4848564E-3,-6.916335E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":83,"left_children":[1,-1,-1],"loss_changes":[7.046892E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.999586E-2,6.4848564E-3,-6.916335E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4598166E2,1.4255491E1,1.3172618E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.7141813E-2,-1.5662872E-3,2.7514067E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":84,"left_children":[1,-1,-1],"loss_changes":[5.998867E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[9.089365E-3,-1.5662872E-3,2.7514067E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4508372E2,9.852733E1,4.6556396E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.117414E-3,5.776981E-3,-1.4892998E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":85,"left_children":[1,-1,-1],"loss_changes":[1.2246013E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.2249134E-2,5.776981E-3,-1.4892998E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3886636E2,2.8279598E1,1.1058676E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.361813E-2,-3.2302486E-3,1.6626043E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":86,"left_children":[1,-1,-1],"loss_changes":[7.453487E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.3878913E-2,-3.2302486E-3,1.6626043E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.486539E2,4.2968697E1,1.05685196E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.2030694E-2,5.6228256E-3,-7.258168E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":87,"left_children":[1,-1,-1],"loss_changes":[7.3450103E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.9976046E-2,5.6228256E-3,-7.258168E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4189871E2,2.0410196E1,1.2148851E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.1137002E-2,1.762004E-3,-2.1862437E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":88,"left_children":[1,-1,-1],"loss_changes":[5.1534414E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,1.762004E-3,-2.1862437E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.447896E2,9.547098E1,4.931863E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.7673045E-2,5.8077965E-3,-6.739307E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":89,"left_children":[1,-1,-1],"loss_changes":[8.363161E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.9976046E-2,5.8077965E-3,-6.739307E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4487651E2,2.274995E1,1.2212656E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.4296703E-2,1.7549556E-3,-2.598217E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":90,"left_children":[1,-1,-1],"loss_changes":[6.3769755E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,1.7549556E-3,-2.598217E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.46384E2,9.578993E1,5.0594067E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.8401492E-2,-2.2284954E-3,2.0331112E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":91,"left_children":[1,-1,-1],"loss_changes":[6.4361787E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1039734E-2,-2.2284954E-3,2.0331112E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4084262E2,7.659992E1,6.424269E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.4543752E-2,-1.3804662E-3,5.713511E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":92,"left_children":[1,-1,-1],"loss_changes":[1.44495945E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.2247072E-2,-1.3804662E-3,5.713511E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4338275E2,1.049905E2,3.8392254E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.528267E-2,-7.871039E-4,3.6181202E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":93,"left_children":[1,-1,-1],"loss_changes":[5.6094213E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.3832384E-2,-7.871039E-4,3.6181202E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.411989E2,1.0199574E2,3.9203144E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.7666913E-2,-2.7777995E-3,2.274628E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":94,"left_children":[1,-1,-1],"loss_changes":[9.257436E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-4.4922787E-3,-2.7777995E-3,2.274628E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4342493E2,7.5238205E1,6.818672E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.0223958E-3,4.197962E-3,-9.195226E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":95,"left_children":[1,-1,-1],"loss_changes":[5.7753954E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7963655E-2,4.197962E-3,-9.195226E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4393094E2,2.6077208E1,1.1785373E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.741426E-3,-2.1122326E-3,4.256295E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":96,"left_children":[1,-1,-1],"loss_changes":[1.3543782E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.058913E-3,-2.1122326E-3,4.256295E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.5196803E2,1.04001495E2,4.7966537E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.3642333E-2,-1.6466811E-3,2.260745E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":97,"left_children":[1,-1,-1],"loss_changes":[5.7697167E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8153457E-2,-1.6466811E-3,2.260745E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4937975E2,7.748587E1,7.189388E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.382149E-2,-7.218605E-4,3.799671E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":98,"left_children":[1,-1,-1],"loss_changes":[6.3202343E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[9.089365E-3,-7.218605E-4,3.799671E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3978E2,9.516022E1,4.4619778E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.86676E-2,-1.8390688E-3,4.3881587E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":99,"left_children":[1,-1,-1],"loss_changes":[9.750232E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8341033E-2,-1.8390688E-3,4.3881587E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3843217E2,1.0661671E2,3.1815464E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.582073E-2,-8.218773E-4,5.8528166E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":100,"left_children":[1,-1,-1],"loss_changes":[1.1306679E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8198002E-2,-8.218773E-4,5.8528166E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4543471E2,1.1384031E2,3.1594398E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.711515E-3,-4.6713003E-3,1.992272E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":101,"left_children":[1,-1,-1],"loss_changes":[1.2732176E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.7214758E-2,-4.6713003E-3,1.992272E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3886119E2,3.907628E1,9.978491E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.637917E-2,7.609872E-3,-2.4956896E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":102,"left_children":[1,-1,-1],"loss_changes":[4.433442E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-7.405935E-2,7.609872E-3,-2.4956896E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4242332E2,6.5749826E0,1.3584834E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.1468275E-2,-1.0023412E-3,5.828316E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":103,"left_children":[1,-1,-1],"loss_changes":[1.1539592E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.7747661E-2,-1.0023412E-3,5.828316E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4143025E2,1.1065111E2,3.0779142E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.694133E-2,-1.497643E-3,4.2880434E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":104,"left_children":[1,-1,-1],"loss_changes":[1.046662E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-1.497643E-3,4.2880434E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.411811E2,9.604003E1,4.5141068E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.5800022E-3,-1.2026948E-3,3.6217147E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":105,"left_children":[1,-1,-1],"loss_changes":[6.642988E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.2026948E-3,3.6217147E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4839073E2,1.1110036E2,3.7290375E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.973296E-2,-2.4801062E-3,1.6485538E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":106,"left_children":[1,-1,-1],"loss_changes":[5.9934816E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.928212E-3,-2.4801062E-3,1.6485538E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3890282E2,7.2114204E1,6.678861E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.7782768E-2,4.787402E-3,-4.2302976E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":107,"left_children":[1,-1,-1],"loss_changes":[5.675418E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.8318826E-2,4.787402E-3,-4.2302976E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4466489E2,2.4265915E1,1.2039897E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.9882852E-2,3.0675808E-3,-9.852684E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":108,"left_children":[1,-1,-1],"loss_changes":[4.9975824E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.659904E-2,3.0675808E-3,-9.852684E-4],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3871518E2,4.3510193E1,9.520499E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-8.3249256E-2,2.1701793E-3,-2.4132612E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":109,"left_children":[1,-1,-1],"loss_changes":[6.9809422E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.4326648E-2,2.1701793E-3,-2.4132612E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4497127E2,4.9870102E1,9.5101166E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.33505E-2,-3.3528213E-3,1.7245552E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":110,"left_children":[1,-1,-1],"loss_changes":[8.994865E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7545339E-2,-3.3528213E-3,1.7245552E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.428226E2,5.7636604E1,8.5186E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.888662E-3,7.4761716E-4,-5.8098906E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":111,"left_children":[1,-1,-1],"loss_changes":[5.8961406E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.707131E-2,7.4761716E-4,-5.8098906E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4379701E2,1.2947508E2,1.4321941E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.4731433E-3,-1.410875E-3,3.668946E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":112,"left_children":[1,-1,-1],"loss_changes":[7.434004E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.410875E-3,3.668946E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4384091E2,1.05325195E2,3.8515717E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.4615412E-2,6.350627E-3,-1.3763421E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":113,"left_children":[1,-1,-1],"loss_changes":[8.152206E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,6.350627E-3,-1.3763421E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3985449E2,1.4311572E1,1.25542915E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.7190799E-2,2.4476429E-5,-1.0347804E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":114,"left_children":[1,-1,-1],"loss_changes":[4.3760467E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[8.075588E-2,2.4476429E-5,-1.0347804E-2],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4545071E2,1.4226358E2,3.1871397E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-7.690015E-4,5.173719E-3,-1.1612984E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":115,"left_children":[1,-1,-1],"loss_changes":[8.88159E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,5.173719E-3,-1.1612984E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4658305E2,2.605823E1,1.20524826E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[7.646015E-3,-1.8375015E-3,3.719586E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":116,"left_children":[1,-1,-1],"loss_changes":[1.0111582E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.100592E-3,-1.8375015E-3,3.719586E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.430344E2,9.409568E1,4.8938713E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.082568E-2,-1.4123493E-3,3.0563455E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":117,"left_children":[1,-1,-1],"loss_changes":[7.3859444E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-1.4123493E-3,3.0563455E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4630136E2,7.049129E1,7.5810074E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[8.82084E-2,-4.5910752E-3,2.0827292E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":118,"left_children":[1,-1,-1],"loss_changes":[9.487183E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.6065094E-2,-4.5910752E-3,2.0827292E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.419174E2,2.502351E1,1.1689389E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.3451144E-2,-1.4754997E-3,3.3577671E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":119,"left_children":[1,-1,-1],"loss_changes":[6.5643044E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.4754997E-3,3.3577671E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.451372E2,1.0830978E2,3.6827427E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.7469175E-2,2.0088356E-3,-3.1262967E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":120,"left_children":[1,-1,-1],"loss_changes":[9.347199E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[9.139376E-3,2.0088356E-3,-3.1262967E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4056224E2,7.54634E1,6.509885E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.987013E-3,2.96393E-4,-1.4292472E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":121,"left_children":[1,-1,-1],"loss_changes":[5.1235256E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.892705E-2,2.96393E-4,-1.4292472E-2],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4270961E2,1.4126088E2,1.4487234E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.457303E-2,-3.6156267E-5,-5.600261E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":122,"left_children":[1,-1,-1],"loss_changes":[3.160904E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.535227E-2,-3.6156267E-5,-5.600261E-3],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4881932E2,1.387976E2,1.0021709E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.4538245E-2,-1.5663367E-3,4.1039074E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":123,"left_children":[1,-1,-1],"loss_changes":[8.494165E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.8198002E-2,-1.5663367E-3,4.1039074E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4572884E2,1.1227029E2,3.3458553E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.4733746E-2,-1.2249603E-3,3.8862335E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":124,"left_children":[1,-1,-1],"loss_changes":[7.597682E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.2249603E-3,3.8862335E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4614978E2,1.0740207E2,3.8747715E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.5157714E-3,2.0361345E-3,-3.810192E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":125,"left_children":[1,-1,-1],"loss_changes":[1.0534019E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,2.0361345E-3,-3.810192E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.3425436E2,8.815093E1,4.6103436E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[3.492384E-2,6.9870725E-3,-3.8937957E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":126,"left_children":[1,-1,-1],"loss_changes":[7.0800476E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.999586E-2,6.9870725E-3,-3.8937957E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4285263E2,1.3457021E1,1.2939561E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.056154E-2,6.1418763E-3,-5.9028633E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":127,"left_children":[1,-1,-1],"loss_changes":[6.239878E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.999586E-2,6.1418763E-3,-5.9028633E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4668265E2,1.4353594E1,1.3232906E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-5.847917E-3,1.3264207E-3,-3.948548E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":128,"left_children":[1,-1,-1],"loss_changes":[7.969706E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.1135263E-2,1.3264207E-3,-3.948548E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4596136E2,1.081264E2,3.7834957E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.4257937E-2,2.5369525E-3,-2.0926907E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":129,"left_children":[1,-1,-1],"loss_changes":[7.2876554E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.1324542E-2,2.5369525E-3,-2.0926907E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4255714E2,5.3719913E1,8.883723E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.567343E-2,1.1114114E-2,-1.0379721E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":130,"left_children":[1,-1,-1],"loss_changes":[5.6073337E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-8.784212E-2,1.1114114E-2,-1.0379721E-4],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4195314E2,3.6036117E0,1.3834952E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[8.889268E-2,2.552067E-3,-2.2335213E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":131,"left_children":[1,-1,-1],"loss_changes":[7.3899565E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1071337E-2,2.552067E-3,-2.2335213E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4020659E2,9.159964E1,4.8606945E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.7582164E-2,-2.7943244E-3,1.9069384E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":132,"left_children":[1,-1,-1],"loss_changes":[8.204838E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-7.698888E-3,-2.7943244E-3,1.9069384E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4655446E2,7.4191246E1,7.236321E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[5.056073E-2,-3.2775572E-3,3.0141624E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":133,"left_children":[1,-1,-1],"loss_changes":[1.3130512E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7545339E-2,-3.2775572E-3,3.0141624E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3631656E2,5.4228195E1,8.208836E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.2223368E-2,7.136852E-5,-7.7421293E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":134,"left_children":[1,-1,-1],"loss_changes":[5.4937963E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.08018E-2,7.136852E-5,-7.7421293E-3],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.5089853E2,1.422935E2,8.605021E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[9.7942855E-3,-3.0662306E-3,1.559495E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":135,"left_children":[1,-1,-1],"loss_changes":[6.7805257E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.494692E-2,-3.0662306E-3,1.559495E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4458452E2,4.5336266E1,9.9248245E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[6.53328E-2,-1.4624465E-3,2.6721095E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":136,"left_children":[1,-1,-1],"loss_changes":[5.8475823E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.210526E-3,-1.4624465E-3,2.6721095E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3498955E2,6.604597E1,6.894358E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.952945E-2,-1.1806671E-3,6.9595138E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":137,"left_children":[1,-1,-1],"loss_changes":[5.3858194E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[5.0932735E-2,-1.1806671E-3,6.9595138E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4174648E2,1.3408994E2,7.656551E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.7021086E-2,1.1512556E-3,-4.2241714E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":138,"left_children":[1,-1,-1],"loss_changes":[8.041847E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[3.073858E-2,1.1512556E-3,-4.2241714E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4121736E2,1.0439554E2,3.6821827E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.7416467E-2,-2.1113497E-4,-1.4636325E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":139,"left_children":[1,-1,-1],"loss_changes":[5.5256176E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.892705E-2,-2.1113497E-4,-1.4636325E-2],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.4816557E2,1.4646033E2,1.7052568E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.3577094E-2,5.4716347E-3,-1.471239E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":140,"left_children":[1,-1,-1],"loss_changes":[4.294382E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.858291E-2,5.4716347E-3,-1.471239E-4],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4502312E2,1.4174747E1,1.3084837E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-2.150772E-2,2.960729E-4,-1.2737393E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":141,"left_children":[1,-1,-1],"loss_changes":[9.10952E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[7.847638E-2,2.960729E-4,-1.2737393E-2],"split_indices":[5,0,0],"split_type":[0,0,0],"sum_hessian":[1.4072964E2,1.3614854E2,4.581109E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.8837075E-2,6.9243886E-4,-1.0116907E-2],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":142,"left_children":[1,-1,-1],"loss_changes":[5.689644E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[6.2219393E-2,6.9243886E-4,-1.0116907E-2],"split_indices":[6,0,0],"split_type":[0,0,0],"sum_hessian":[1.3265845E2,1.2859805E2,4.060395E0],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-6.4753786E-2,2.235526E-3,-1.6641989E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":143,"left_children":[1,-1,-1],"loss_changes":[4.180998E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-9.93766E-3,2.235526E-3,-1.6641989E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.4037341E2,3.6282894E1,1.0409052E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[1.3361551E-2,-1.3775323E-3,6.05119E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":144,"left_children":[1,-1,-1],"loss_changes":[1.3271535E1,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.1037463E-2,-1.3775323E-3,6.05119E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4648033E2,1.1729451E2,2.9185825E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-1.0920584E-1,-4.844441E-3,4.0909523E-4],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":145,"left_children":[1,-1,-1],"loss_changes":[7.881714E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-2.538787E-2,-4.844441E-3,4.0909523E-4],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.3857092E2,3.895908E1,9.961184E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.769877E-2,1.0061163E-3,-3.4220829E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":146,"left_children":[1,-1,-1],"loss_changes":[6.3169985E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[2.3529412E-2,1.0061163E-3,-3.4220829E-3],"split_indices":[2,0,0],"split_type":[0,0,0],"sum_hessian":[1.4283556E2,9.543456E1,4.7400986E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.444409E-2,-2.7583702E-3,1.9868303E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":147,"left_children":[1,-1,-1],"loss_changes":[8.457398E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-5.928212E-3,-2.7583702E-3,1.9868303E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4835847E2,7.594465E1,7.241383E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-3.7292324E-2,-3.1595018E-3,1.4861865E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":148,"left_children":[1,-1,-1],"loss_changes":[7.614424E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.7545339E-2,-3.1595018E-3,1.4861865E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4507446E2,5.7775925E1,8.729854E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[4.9239013E-2,6.3658333E-3,-2.813095E-5],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":149,"left_children":[1,-1,-1],"loss_changes":[4.295668E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-3.5148077E-2,6.3658333E-3,-2.813095E-5],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3944896E2,1.0438096E1,1.2901086E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[2.464643E-3,-1.2541604E-3,3.4766563E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":150,"left_children":[1,-1,-1],"loss_changes":[6.311665E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[1.4175258E-2,-1.2541604E-3,3.4766563E-3],"split_indices":[1,0,0],"split_type":[0,0,0],"sum_hessian":[1.4098953E2,1.03342636E2,3.7646885E1],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}},{"base_weights":[-4.6441153E-2,3.940563E-3,-1.4309208E-3],"categories":[],"categories_nodes":[],"categories_segments":[],"categories_sizes":[],"default_left":[0,0,0],"id":151,"left_children":[1,-1,-1],"loss_changes":[6.005825E0,0E0,0E0],"parents":[2147483647,0,0],"right_children":[2,-1,-1],"split_conditions":[-1.761174E-2,3.940563E-3,-1.4309208E-3],"split_indices":[3,0,0],"split_type":[0,0,0],"sum_hessian":[1.3874187E2,2.4410618E1,1.14331245E2],"tree_param":{"num_deleted":"0","num_feature":"7","num_nodes":"3","size_leaf_vector":"1"}}]},"name":"gbtree"},"learner_model_param":{"base_score":"[5.8194774E-1]","boost_from_average":"1","num_class":"0","num_feature":"7","num_target":"1"},"objective":{"name":"binary:logistic","reg_loss_param":{"scale_pos_weight":"1"}}},"version":[3,2,0]} \ No newline at end of file diff --git a/notebooks/models/spy_xgb_v1_meta.json b/notebooks/models/spy_xgb_v1_meta.json index 63d3f75..9216b93 100644 --- a/notebooks/models/spy_xgb_v1_meta.json +++ b/notebooks/models/spy_xgb_v1_meta.json @@ -1,5 +1,5 @@ { - "p_base": 0.5833333333333334, + "p_base": 0.5819477434679335, "feature_cols": [ "VIX_rank_20", "TLT_ret_10", @@ -9,5 +9,5 @@ "SPY_ret_20", "SPY_dist_sma50" ], - "last_trained_date": "2026-07-24 00:00:00" + "last_trained_date": "2026-07-29 00:00:00" } \ No newline at end of file diff --git a/notebooks/spy_direction_dataset.ipynb b/notebooks/spy_direction_dataset.ipynb index f59b6a6..ec932d3 100644 --- a/notebooks/spy_direction_dataset.ipynb +++ b/notebooks/spy_direction_dataset.ipynb @@ -20,14 +20,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(PosixPath('/home/jarno/repos/trading-bot'),\n", - " PosixPath('/home/jarno/repos/trading-bot/data/ibkr/daily'),\n", + " PosixPath('/home/jarno/repos/trading-bot/data/alpaca/daily'),\n", " PosixPath('/home/jarno/repos/trading-bot/data/training/spy_direction_5d.parquet'))" ] }, @@ -87,16 +87,16 @@ "output_type": "stream", "text": [ "\n", - "DatetimeIndex: 1251 entries, 2021-07-30 to 2026-07-24\n", + "DatetimeIndex: 1255 entries, 2021-08-02 to 2026-07-31\n", "Data columns (total 4 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", - " 0 SPY_close 1251 non-null float64\n", - " 1 VIX_close 1251 non-null float64\n", - " 2 TLT_close 1251 non-null float64\n", - " 3 USO_close 1251 non-null float64\n", + " 0 SPY_close 1255 non-null float64\n", + " 1 VIX_close 1255 non-null float64\n", + " 2 TLT_close 1255 non-null float64\n", + " 3 USO_close 1255 non-null float64\n", "dtypes: float64(4)\n", - "memory usage: 48.9 KB\n" + "memory usage: 49.0 KB\n" ] }, { @@ -135,40 +135,40 @@ " \n", " \n", " \n", - " 2021-07-30\n", - " 438.51\n", - " 495.4\n", - " 149.52\n", - " 50.66\n", - " \n", - " \n", " 2021-08-02\n", " 437.59\n", - " 513.6\n", + " 25.68\n", " 150.67\n", " 49.18\n", " \n", " \n", " 2021-08-03\n", " 441.15\n", - " 488.0\n", + " 24.40\n", " 150.75\n", " 48.85\n", " \n", " \n", " 2021-08-04\n", " 438.98\n", - " 487.6\n", + " 24.38\n", " 151.06\n", " 47.20\n", " \n", " \n", " 2021-08-05\n", " 441.76\n", - " 474.8\n", + " 23.74\n", " 150.29\n", " 48.10\n", " \n", + " \n", + " 2021-08-06\n", + " 442.49\n", + " 23.14\n", + " 147.78\n", + " 47.57\n", + " \n", " \n", "\n", "" @@ -176,11 +176,11 @@ "text/plain": [ " SPY_close VIX_close TLT_close USO_close\n", "date \n", - "2021-07-30 438.51 495.4 149.52 50.66\n", - "2021-08-02 437.59 513.6 150.67 49.18\n", - "2021-08-03 441.15 488.0 150.75 48.85\n", - "2021-08-04 438.98 487.6 151.06 47.20\n", - "2021-08-05 441.76 474.8 150.29 48.10" + "2021-08-02 437.59 25.68 150.67 49.18\n", + "2021-08-03 441.15 24.40 150.75 48.85\n", + "2021-08-04 438.98 24.38 151.06 47.20\n", + "2021-08-05 441.76 23.74 150.29 48.10\n", + "2021-08-06 442.49 23.14 147.78 47.57" ] }, "execution_count": 2, @@ -234,7 +234,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -283,24 +283,12 @@ " \n", " \n", " \n", - " 2021-10-08\n", - " 0.008336\n", - " -0.017017\n", - " -0.011155\n", - " -0.075239\n", - " 0.125\n", - " -0.034239\n", - " 0.041495\n", - " 0.032998\n", - " 1.0\n", - " \n", - " \n", " 2021-10-11\n", " 0.014114\n", " -0.026625\n", " -0.018145\n", " -0.090869\n", - " 0.200\n", + " 0.20\n", " -0.033135\n", " 0.031015\n", " 0.038908\n", @@ -312,7 +300,7 @@ " -0.023752\n", " -0.020386\n", " -0.074091\n", - " 0.100\n", + " 0.10\n", " -0.001041\n", " 0.008628\n", " -0.001303\n", @@ -324,7 +312,7 @@ " -0.028356\n", " -0.016597\n", " -0.081006\n", - " 0.050\n", + " 0.05\n", " 0.006928\n", " 0.036928\n", " -0.005897\n", @@ -336,12 +324,24 @@ " -0.010443\n", " -0.000214\n", " -0.096759\n", - " 0.050\n", + " 0.05\n", " 0.010809\n", " 0.026192\n", " -0.011991\n", " 1.0\n", " \n", + " \n", + " 2021-10-15\n", + " 0.018294\n", + " 0.010127\n", + " 0.007213\n", + " -0.079882\n", + " 0.05\n", + " -0.002202\n", + " 0.030287\n", + " -0.003823\n", + " 1.0\n", + " \n", " \n", "\n", "" @@ -349,22 +349,22 @@ "text/plain": [ " SPY_ret_5 SPY_ret_20 SPY_dist_sma50 VIX_change_5 VIX_rank_20 \\\n", "date \n", - "2021-10-08 0.008336 -0.017017 -0.011155 -0.075239 0.125 \n", - "2021-10-11 0.014114 -0.026625 -0.018145 -0.090869 0.200 \n", - "2021-10-12 0.001201 -0.023752 -0.020386 -0.074091 0.100 \n", - "2021-10-13 0.000644 -0.028356 -0.016597 -0.081006 0.050 \n", - "2021-10-14 0.008754 -0.010443 -0.000214 -0.096759 0.050 \n", + "2021-10-11 0.014114 -0.026625 -0.018145 -0.090869 0.20 \n", + "2021-10-12 0.001201 -0.023752 -0.020386 -0.074091 0.10 \n", + "2021-10-13 0.000644 -0.028356 -0.016597 -0.081006 0.05 \n", + "2021-10-14 0.008754 -0.010443 -0.000214 -0.096759 0.05 \n", + "2021-10-15 0.018294 0.010127 0.007213 -0.079882 0.05 \n", "\n", " TLT_ret_10 USO_ret_5 SPY_TLT_ratio_ret spy_up_5d \n", "date \n", - "2021-10-08 -0.034239 0.041495 0.032998 1.0 \n", "2021-10-11 -0.033135 0.031015 0.038908 1.0 \n", "2021-10-12 -0.001041 0.008628 -0.001303 1.0 \n", "2021-10-13 0.006928 0.036928 -0.005897 1.0 \n", - "2021-10-14 0.010809 0.026192 -0.011991 1.0 " + "2021-10-14 0.010809 0.026192 -0.011991 1.0 \n", + "2021-10-15 -0.002202 0.030287 -0.003823 1.0 " ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -384,7 +384,7 @@ "df[\"TLT_ret_10\"] = df[\"TLT_close\"].pct_change(10)\n", "df[\"USO_ret_5\"] = df[\"USO_close\"].pct_change(5)\n", "df[\"SPY_TLT_ratio_ret\"] = (df[\"SPY_close\"] / df[\"TLT_close\"]).pct_change(5)\n", - "df_model\n", + "\n", "spy_forward_close = df[\"SPY_close\"].shift(-5)\n", "df[\"spy_up_5d\"] = np.nan\n", "df.loc[spy_forward_close > df[\"SPY_close\"], \"spy_up_5d\"] = 1.0\n", @@ -418,7 +418,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -458,24 +458,24 @@ " \n", " \n", " train\n", - " 837\n", - " 2021-10-08\n", - " 2025-02-07\n", - " 0.583035\n", + " 840\n", + " 2021-10-11\n", + " 2025-02-13\n", + " 0.583333\n", " \n", " \n", " validation\n", - " 179\n", - " 2025-02-10\n", - " 2025-10-24\n", - " 0.653631\n", + " 180\n", + " 2025-02-14\n", + " 2025-10-31\n", + " 0.633333\n", " \n", " \n", " test\n", " 181\n", - " 2025-10-27\n", - " 2026-07-17\n", - " 0.558011\n", + " 2025-11-03\n", + " 2026-07-24\n", + " 0.569061\n", " \n", " \n", "\n", @@ -484,12 +484,12 @@ "text/plain": [ " rows start_date end_date target_mean\n", "split \n", - "train 837 2021-10-08 2025-02-07 0.583035\n", - "validation 179 2025-02-10 2025-10-24 0.653631\n", - "test 181 2025-10-27 2026-07-17 0.558011" + "train 840 2021-10-11 2025-02-13 0.583333\n", + "validation 180 2025-02-14 2025-10-31 0.633333\n", + "test 181 2025-11-03 2026-07-24 0.569061" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -543,17 +543,17 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Rows: 1,197\n", + "Rows: 1,201\n", "Feature columns: ['SPY_ret_5', 'SPY_ret_20', 'SPY_dist_sma50', 'VIX_change_5', 'VIX_rank_20', 'TLT_ret_10', 'USO_ret_5', 'SPY_TLT_ratio_ret']\n", "Target column: spy_up_5d\n", - "Training matrix shape: (837, 8)\n" + "Training matrix shape: (840, 8)\n" ] }, { @@ -592,16 +592,16 @@ " \n", " \n", " count\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197.000000\n", - " 1197\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201.000000\n", + " 1201\n", " \n", " \n", " unique\n", @@ -640,32 +640,32 @@ " NaN\n", " NaN\n", " NaN\n", - " 837\n", + " 840\n", " \n", " \n", " mean\n", - " 0.002556\n", - " 0.009841\n", - " 0.011067\n", - " -0.008646\n", - " 0.387009\n", - " -0.004083\n", - " 0.004662\n", - " 0.004927\n", - " 0.589808\n", + " 0.002502\n", + " 0.009848\n", + " 0.011028\n", + " 0.017763\n", + " 0.403476\n", + " -0.004099\n", + " 0.005024\n", + " 0.004880\n", + " 0.588676\n", " NaN\n", " \n", " \n", " std\n", - " 0.023081\n", - " 0.043634\n", - " 0.037371\n", - " 0.092413\n", - " 0.333697\n", - " 0.028557\n", - " 0.052319\n", - " 0.027656\n", - " 0.492074\n", + " 0.023057\n", + " 0.043558\n", + " 0.037315\n", + " 0.299417\n", + " 0.337501\n", + " 0.028502\n", + " 0.052628\n", + " 0.027606\n", + " 0.492279\n", " NaN\n", " \n", " \n", @@ -683,40 +683,40 @@ " \n", " \n", " 25%\n", - " -0.009535\n", - " -0.017017\n", - " -0.008847\n", - " -0.058376\n", - " 0.075000\n", - " -0.023517\n", - " -0.026200\n", + " -0.009601\n", + " -0.016509\n", + " -0.008656\n", + " -0.056615\n", + " 0.100000\n", + " -0.023304\n", + " -0.025866\n", " -0.010013\n", " 0.000000\n", " NaN\n", " \n", " \n", " 50%\n", - " 0.003869\n", - " 0.015797\n", - " 0.017906\n", - " -0.020655\n", - " 0.250000\n", - " -0.004339\n", - " 0.004817\n", - " 0.005710\n", + " 0.003798\n", + " 0.015725\n", + " 0.017802\n", + " -0.018570\n", + " 0.300000\n", + " -0.004435\n", + " 0.004950\n", + " 0.005537\n", " 1.000000\n", " NaN\n", " \n", " \n", " 75%\n", - " 0.015957\n", - " 0.038385\n", - " 0.038332\n", - " 0.027778\n", - " 0.700000\n", - " 0.014272\n", - " 0.031883\n", - " 0.021406\n", + " 0.015955\n", + " 0.038179\n", + " 0.038282\n", + " 0.030814\n", + " 0.750000\n", + " 0.014227\n", + " 0.032486\n", + " 0.021390\n", " 1.000000\n", " NaN\n", " \n", @@ -724,8 +724,8 @@ " max\n", " 0.082843\n", " 0.157566\n", - " 0.088103\n", - " 0.937828\n", + " 0.088105\n", + " 3.846154\n", " 1.000000\n", " 0.091322\n", " 0.327273\n", @@ -739,33 +739,33 @@ ], "text/plain": [ " SPY_ret_5 SPY_ret_20 SPY_dist_sma50 VIX_change_5 VIX_rank_20 \\\n", - "count 1197.000000 1197.000000 1197.000000 1197.000000 1197.000000 \n", + "count 1201.000000 1201.000000 1201.000000 1201.000000 1201.000000 \n", "unique NaN NaN NaN NaN NaN \n", "top NaN NaN NaN NaN NaN \n", "freq NaN NaN NaN NaN NaN \n", - "mean 0.002556 0.009841 0.011067 -0.008646 0.387009 \n", - "std 0.023081 0.043634 0.037371 0.092413 0.333697 \n", + "mean 0.002502 0.009848 0.011028 0.017763 0.403476 \n", + "std 0.023057 0.043558 0.037315 0.299417 0.337501 \n", "min -0.114962 -0.123975 -0.141995 -0.387709 0.050000 \n", - "25% -0.009535 -0.017017 -0.008847 -0.058376 0.075000 \n", - "50% 0.003869 0.015797 0.017906 -0.020655 0.250000 \n", - "75% 0.015957 0.038385 0.038332 0.027778 0.700000 \n", - "max 0.082843 0.157566 0.088103 0.937828 1.000000 \n", + "25% -0.009601 -0.016509 -0.008656 -0.056615 0.100000 \n", + "50% 0.003798 0.015725 0.017802 -0.018570 0.300000 \n", + "75% 0.015955 0.038179 0.038282 0.030814 0.750000 \n", + "max 0.082843 0.157566 0.088105 3.846154 1.000000 \n", "\n", " TLT_ret_10 USO_ret_5 SPY_TLT_ratio_ret spy_up_5d split \n", - "count 1197.000000 1197.000000 1197.000000 1197.000000 1197 \n", + "count 1201.000000 1201.000000 1201.000000 1201.000000 1201 \n", "unique NaN NaN NaN NaN 3 \n", "top NaN NaN NaN NaN train \n", - "freq NaN NaN NaN NaN 837 \n", - "mean -0.004083 0.004662 0.004927 0.589808 NaN \n", - "std 0.028557 0.052319 0.027656 0.492074 NaN \n", + "freq NaN NaN NaN NaN 840 \n", + "mean -0.004099 0.005024 0.004880 0.588676 NaN \n", + "std 0.028502 0.052628 0.027606 0.492279 NaN \n", "min -0.092880 -0.196652 -0.117208 0.000000 NaN \n", - "25% -0.023517 -0.026200 -0.010013 0.000000 NaN \n", - "50% -0.004339 0.004817 0.005710 1.000000 NaN \n", - "75% 0.014272 0.031883 0.021406 1.000000 NaN \n", + "25% -0.023304 -0.025866 -0.010013 0.000000 NaN \n", + "50% -0.004435 0.004950 0.005537 1.000000 NaN \n", + "75% 0.014227 0.032486 0.021390 1.000000 NaN \n", "max 0.091322 0.327273 0.129204 1.000000 NaN " ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -787,30 +787,30 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(PosixPath('/home/jarno/repos/trading-bot/data/training/spy_direction_5d.parquet'),\n", - " (1197, 11),\n", + " (1201, 11),\n", " date SPY_ret_5 SPY_ret_20 SPY_dist_sma50 VIX_change_5 \\\n", - " 0 2021-10-08 0.008336 -0.017017 -0.011155 -0.075239 \n", - " 1 2021-10-11 0.014114 -0.026625 -0.018145 -0.090869 \n", - " 2 2021-10-12 0.001201 -0.023752 -0.020386 -0.074091 \n", - " 3 2021-10-13 0.000644 -0.028356 -0.016597 -0.081006 \n", - " 4 2021-10-14 0.008754 -0.010443 -0.000214 -0.096759 \n", + " 0 2021-10-11 0.014114 -0.026625 -0.018145 -0.090869 \n", + " 1 2021-10-12 0.001201 -0.023752 -0.020386 -0.074091 \n", + " 2 2021-10-13 0.000644 -0.028356 -0.016597 -0.081006 \n", + " 3 2021-10-14 0.008754 -0.010443 -0.000214 -0.096759 \n", + " 4 2021-10-15 0.018294 0.010127 0.007213 -0.079882 \n", " \n", " VIX_rank_20 TLT_ret_10 USO_ret_5 SPY_TLT_ratio_ret spy_up_5d split \n", - " 0 0.125 -0.034239 0.041495 0.032998 1.0 train \n", - " 1 0.200 -0.033135 0.031015 0.038908 1.0 train \n", - " 2 0.100 -0.001041 0.008628 -0.001303 1.0 train \n", - " 3 0.050 0.006928 0.036928 -0.005897 1.0 train \n", - " 4 0.050 0.010809 0.026192 -0.011991 1.0 train )" + " 0 0.20 -0.033135 0.031015 0.038908 1.0 train \n", + " 1 0.10 -0.001041 0.008628 -0.001303 1.0 train \n", + " 2 0.05 0.006928 0.036928 -0.005897 1.0 train \n", + " 3 0.05 0.010809 0.026192 -0.011991 1.0 train \n", + " 4 0.05 -0.002202 0.030287 -0.003823 1.0 train )" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/train-xboost.ipynb b/notebooks/train-xboost.ipynb index e69de29..d436e3b 100644 --- a/notebooks/train-xboost.ipynb +++ b/notebooks/train-xboost.ipynb @@ -0,0 +1,336 @@ +{ + "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": [ + "
" + ] + }, + "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 +} diff --git a/src/trading_bot/data/alpaca_daily_lib.py b/src/trading_bot/data/alpaca_daily_lib.py new file mode 100644 index 0000000..537c3f7 --- /dev/null +++ b/src/trading_bot/data/alpaca_daily_lib.py @@ -0,0 +1,255 @@ +"""Shared Alpaca daily candle helpers used by both the CLI fetcher and inference refreshes.""" + +from __future__ import annotations + +import argparse +import os +import re +from dataclasses import dataclass +from datetime import date, datetime, time, timedelta +from pathlib import Path +from zoneinfo import ZoneInfo + +import pandas as pd +from dotenv import load_dotenv + +# Load environment variables from .env file if available +load_dotenv() + +DEFAULT_OUTPUT_DIR = Path("data/alpaca/daily") +DEFAULT_DURATION = "1 W" +EASTERN_TZ = ZoneInfo("America/New_York") +DURATION_PATTERN = re.compile(r"^(\d+)\s*([DWMY])$") + + +@dataclass(frozen=True) +class DailyCandle: + """Daily OHLCV market data for one trading session.""" + + trading_day: date + open: float + high: float + low: float + close: float + volume: int + + +def default_end_date() -> date: + """Return yesterday's date in the US/Eastern market timezone.""" + + return datetime.now(EASTERN_TZ).date() - timedelta(days=1) + + +def current_market_date() -> date: + """Return today's date in the US/Eastern market timezone.""" + + return datetime.now(EASTERN_TZ).date() + + +def parse_end_date(value: str) -> date: + """Parse an end date in YYYYMMDD format.""" + + try: + return datetime.strptime(value, "%Y%m%d").date() + except ValueError as exc: + raise argparse.ArgumentTypeError( + "end date must use YYYYMMDD format, such as 20250605" + ) from exc + + +def parse_duration(value: str) -> str: + """Normalize and validate a duration string like '1 W' or '1 M'.""" + + normalized = " ".join(value.upper().split()) + if not DURATION_PATTERN.fullmatch(normalized): + raise argparse.ArgumentTypeError( + "duration must look like '1 D', '1 W', '1 M', or '1 Y'" + ) + return normalized + + +def duration_to_start_date(end_date: date, duration: str) -> date: + """Calculate the start date based on end date and a duration string.""" + + match = DURATION_PATTERN.match(duration) + if not match: + raise ValueError(f"Invalid duration format: {duration}") + + amount = int(match.group(1)) + unit = match.group(2) + + if unit == "D": + return end_date - timedelta(days=amount) + if unit == "W": + return end_date - timedelta(weeks=amount) + if unit == "M": + return end_date - timedelta(days=amount * 30) + if unit == "Y": + return end_date - timedelta(days=amount * 365) + + raise ValueError(f"Unsupported duration unit: {unit}") + + +def fetch_daily_candles( + symbol: str, + end_date: date, + duration: str, + api_key: str | None = None, + secret_key: str | None = None, +) -> list[DailyCandle]: + """Fetch daily candles for a symbol using Alpaca Market Data API.""" + + try: + from alpaca.data.historical import StockHistoricalDataClient + from alpaca.data.requests import StockBarsRequest + from alpaca.data.timeframe import TimeFrame + except ImportError as exc: + raise SystemExit( + "Missing dependency: alpaca-py. Install it via 'pip install alpaca-py' " + "before running the script." + ) from exc + + start_date = duration_to_start_date(end_date, duration) + start_dt = datetime.combine(start_date, time.min, tzinfo=EASTERN_TZ) + end_dt = datetime.combine(end_date, time.max, tzinfo=EASTERN_TZ) + + client = StockHistoricalDataClient(api_key=api_key, secret_key=secret_key) + + request_params = StockBarsRequest( + symbol_or_symbols=symbol, + timeframe=TimeFrame.Day, + start=start_dt, + end=end_dt, + ) + + bars = client.get_stock_bars(request_params) + + if not bars or symbol not in bars.data: + print(f"Alpaca returned no historical bars for {symbol}.") + return [] + + candles: list[DailyCandle] = [] + for bar in bars[symbol]: + trading_day = bar.timestamp.astimezone(EASTERN_TZ).date() + candles.append( + DailyCandle( + trading_day=trading_day, + open=float(bar.open), + high=float(bar.high), + low=float(bar.low), + close=float(bar.close), + volume=int(bar.volume), + ) + ) + + return candles + + +def candles_to_frame(symbol: str, candles: list[DailyCandle]) -> pd.DataFrame: + """Convert candles to a date-indexed dataframe ready for Parquet storage.""" + + rows = [ + { + "date": candle.trading_day, + "symbol": symbol, + "open": candle.open, + "high": candle.high, + "low": candle.low, + "close": candle.close, + "volume": candle.volume, + } + for candle in candles + ] + frame = pd.DataFrame.from_records(rows) + if frame.empty: + return pd.DataFrame( + columns=["symbol", "open", "high", "low", "close", "volume"], + index=pd.Index([], name="date"), + ) + + frame["date"] = pd.to_datetime(frame["date"]).dt.date + return frame.set_index("date") + + +def read_existing_candles(path: Path) -> pd.DataFrame: + """Read an existing candle Parquet file as a date-indexed dataframe.""" + + if not path.exists(): + return pd.DataFrame( + columns=["symbol", "open", "high", "low", "close", "volume"], + index=pd.Index([], name="date"), + ) + + frame = pd.read_parquet(path) + if "date" in frame.columns: + frame["date"] = pd.to_datetime(frame["date"]).dt.date + frame = frame.set_index("date") + + frame.index = pd.to_datetime(frame.index).date + frame.index.name = "date" + return frame + + +def oldest_stored_date_or_today(path: Path) -> date: + """Return the oldest stored candle date, or today if no data exists yet.""" + + existing = read_existing_candles(path) + if existing.empty: + return current_market_date() + return min(existing.index) + + +def write_candles(path: Path, symbol: str, candles: list[DailyCandle]) -> pd.DataFrame: + """Append candles to a ticker Parquet file, keeping one row per date.""" + + existing = read_existing_candles(path) + fetched = candles_to_frame(symbol, candles) + combined = pd.concat([existing, fetched]) + if not combined.empty: + combined = combined[~combined.index.duplicated(keep="last")] + combined = combined.sort_index() + + path.parent.mkdir(parents=True, exist_ok=True) + combined.to_parquet(path, index=True) + return combined + + +def print_candles(symbol: str, candles: list[DailyCandle]) -> None: + """Print candles in a compact table.""" + + print("date,symbol,open,high,low,close,volume") + for candle in candles: + print( + f"{candle.trading_day.isoformat()}," + f"{symbol}," + f"{candle.open:.2f}," + f"{candle.high:.2f}," + f"{candle.low:.2f}," + f"{candle.close:.2f}," + f"{candle.volume}" + ) + + +def refresh_recent_market_data( + output_dir: Path | str, + symbols: dict[str, str] | None = None, + api_key: str | None = None, + secret_key: str | None = None, + duration: str = DEFAULT_DURATION, +) -> None: + """Refresh the latest weekly Alpaca candle parquet files for the provided symbols.""" + + output_dir = Path(output_dir) + symbols = symbols or {} + + for symbol in symbols.keys(): + output_path = output_dir / f"{symbol}.parquet" + candles = fetch_daily_candles( + symbol=symbol, + end_date=default_end_date(), + duration=duration, + api_key=api_key, + secret_key=secret_key, + ) + print(f"Fetched {len(candles)} daily candles for {symbol}.") + write_candles(output_path, symbol, candles) diff --git a/src/trading_bot/data/fetch_alpaca_daily.py b/src/trading_bot/data/fetch_alpaca_daily.py index 86f1c4a..ec15763 100644 --- a/src/trading_bot/data/fetch_alpaca_daily.py +++ b/src/trading_bot/data/fetch_alpaca_daily.py @@ -1,236 +1,31 @@ -"""Alpaca daily candle fetcher.""" +"""Alpaca daily candle fetcher CLI wrapper. + +The reusable implementation lives in the shared library module so the same +fetching and parquet persistence logic can be reused by the prediction flow. +""" from __future__ import annotations import argparse import os -import re -from dataclasses import dataclass -from datetime import date, datetime, time, timedelta from pathlib import Path -from zoneinfo import ZoneInfo -import pandas as pd -from dotenv import load_dotenv - -# Load environment variables from .env file if available -load_dotenv() - -DEFAULT_OUTPUT_DIR = Path("data/alpaca/daily") -DEFAULT_DURATION = "1 W" -EASTERN_TZ = ZoneInfo("America/New_York") -DURATION_PATTERN = re.compile(r"^(\d+)\s*([DWMY])$") - - -@dataclass(frozen=True) -class DailyCandle: - """Daily OHLCV market data for one trading session.""" - - trading_day: date - open: float - high: float - low: float - close: float - volume: int - - -def default_end_date() -> date: - """Return yesterday's date in the US/Eastern market timezone.""" - - return datetime.now(EASTERN_TZ).date() - timedelta(days=1) - - -def current_market_date() -> date: - """Return today's date in the US/Eastern market timezone.""" - - return datetime.now(EASTERN_TZ).date() - - -def parse_end_date(value: str) -> date: - """Parse an end date in YYYYMMDD format.""" - - try: - return datetime.strptime(value, "%Y%m%d").date() - except ValueError as exc: - raise argparse.ArgumentTypeError( - "end date must use YYYYMMDD format, such as 20250605" - ) from exc - - -def parse_duration(value: str) -> str: - """Normalize and validate a duration string like '1 W' or '1 M'.""" - - normalized = " ".join(value.upper().split()) - if not DURATION_PATTERN.fullmatch(normalized): - raise argparse.ArgumentTypeError( - "duration must look like '1 D', '1 W', '1 M', or '1 Y'" - ) - return normalized - - -def duration_to_start_date(end_date: date, duration: str) -> date: - """Calculate the start date based on end date and a duration string.""" - - match = DURATION_PATTERN.match(duration) - if not match: - raise ValueError(f"Invalid duration format: {duration}") - - amount = int(match.group(1)) - unit = match.group(2) - - if unit == "D": - return end_date - timedelta(days=amount) - if unit == "W": - return end_date - timedelta(weeks=amount) - if unit == "M": - return end_date - timedelta(days=amount * 30) - if unit == "Y": - return end_date - timedelta(days=amount * 365) - - raise ValueError(f"Unsupported duration unit: {unit}") - - -def fetch_daily_candles( - symbol: str, - end_date: date, - duration: str, - api_key: str | None = None, - secret_key: str | None = None, -) -> list[DailyCandle]: - """Fetch daily candles for a symbol using Alpaca Market Data API.""" - - try: - from alpaca.data.historical import StockHistoricalDataClient - from alpaca.data.requests import StockBarsRequest - from alpaca.data.timeframe import TimeFrame - except ImportError as exc: - raise SystemExit( - "Missing dependency: alpaca-py. Install it via 'pip install alpaca-py' " - "before running the script." - ) from exc - - start_date = duration_to_start_date(end_date, duration) - - start_dt = datetime.combine(start_date, time.min, tzinfo=EASTERN_TZ) - end_dt = datetime.combine(end_date, time.max, tzinfo=EASTERN_TZ) - - print(start_dt, end_dt) - - client = StockHistoricalDataClient(api_key=api_key, secret_key=secret_key) - - request_params = StockBarsRequest( - symbol_or_symbols=symbol, - timeframe=TimeFrame.Day, - start=start_dt, - end=end_dt, - ) - - bars = client.get_stock_bars(request_params) - - if not bars or symbol not in bars.data: - print(f"Alpaca returned no historical bars for {symbol}.") - return [] - - candles: list[DailyCandle] = [] - for bar in bars[symbol]: - trading_day = bar.timestamp.astimezone(EASTERN_TZ).date() - candles.append( - DailyCandle( - trading_day=trading_day, - open=float(bar.open), - high=float(bar.high), - low=float(bar.low), - close=float(bar.close), - volume=int(bar.volume), - ) - ) - - return candles - - -def candles_to_frame(symbol: str, candles: list[DailyCandle]) -> pd.DataFrame: - """Convert candles to a date-indexed dataframe ready for Parquet storage.""" - - rows = [ - { - "date": candle.trading_day, - "symbol": symbol, - "open": candle.open, - "high": candle.high, - "low": candle.low, - "close": candle.close, - "volume": candle.volume, - } - for candle in candles - ] - frame = pd.DataFrame.from_records(rows) - if frame.empty: - return pd.DataFrame( - columns=["symbol", "open", "high", "low", "close", "volume"], - index=pd.Index([], name="date"), - ) - - frame["date"] = pd.to_datetime(frame["date"]).dt.date - return frame.set_index("date") - - -def read_existing_candles(path: Path) -> pd.DataFrame: - """Read an existing candle Parquet file as a date-indexed dataframe.""" - - if not path.exists(): - return pd.DataFrame( - columns=["symbol", "open", "high", "low", "close", "volume"], - index=pd.Index([], name="date"), - ) - - frame = pd.read_parquet(path) - if "date" in frame.columns: - frame["date"] = pd.to_datetime(frame["date"]).dt.date - frame = frame.set_index("date") - - frame.index = pd.to_datetime(frame.index).date - frame.index.name = "date" - return frame - - -def oldest_stored_date_or_today(path: Path) -> date: - """Return the oldest stored candle date, or today if no data exists yet.""" - - existing = read_existing_candles(path) - if existing.empty: - return current_market_date() - return min(existing.index) - - -def write_candles(path: Path, symbol: str, candles: list[DailyCandle]) -> pd.DataFrame: - """Append candles to a ticker Parquet file, keeping one row per date.""" - - existing = read_existing_candles(path) - fetched = candles_to_frame(symbol, candles) - combined = pd.concat([existing, fetched]) - if not combined.empty: - combined = combined[~combined.index.duplicated(keep="last")] - combined = combined.sort_index() - - path.parent.mkdir(parents=True, exist_ok=True) - combined.to_parquet(path, index=True) - return combined - - -def print_candles(symbol: str, candles: list[DailyCandle]) -> None: - """Print candles in a compact table.""" - - print("date,symbol,open,high,low,close,volume") - for candle in candles: - print( - f"{candle.trading_day.isoformat()}," - f"{symbol}," - f"{candle.open:.2f}," - f"{candle.high:.2f}," - f"{candle.low:.2f}," - f"{candle.close:.2f}," - f"{candle.volume}" - ) +from trading_bot.data.alpaca_daily_lib import ( + DEFAULT_DURATION, + DEFAULT_OUTPUT_DIR, + DailyCandle, + candles_to_frame, + current_market_date, + default_end_date, + duration_to_start_date, + fetch_daily_candles, + oldest_stored_date_or_today, + parse_duration, + parse_end_date, + print_candles, + read_existing_candles, + write_candles, +) def parse_args() -> argparse.Namespace: @@ -292,8 +87,6 @@ def main() -> None: else args.end_date or default_end_date() ) - print(oldest_stored_date_or_today(output_path)) - print( f"Fetching {symbol} daily candles ending {end_date:%Y-%m-%d} " f"for duration {args.duration} via Alpaca API" @@ -305,7 +98,6 @@ def main() -> None: api_key=args.api_key, secret_key=args.secret_key, ) - #print_candles(symbol, candles) stored = write_candles(output_path, symbol, candles) print(f"Wrote {len(stored)} total daily rows to {output_path}") diff --git a/src/trading_bot/data/train_pipeline.py b/src/trading_bot/data/train_pipeline.py new file mode 100644 index 0000000..2f045fa --- /dev/null +++ b/src/trading_bot/data/train_pipeline.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +"""Generate training dataset and train an XGBoost model using a JSON config. + +This script combines the logic from notebooks/spy_direction_dataset.ipynb +and notebooks/train-xboost.ipynb into a single runnable script. +""" +from pathlib import Path +import json +import numpy as np +import pandas as pd +import xgboost as xgb +from sklearn.metrics import classification_report, accuracy_score + + +def find_project_root(start: Path | None = None) -> Path: + current = (start or Path.cwd()).resolve() + for candidate in [current, *current.parents]: + if (candidate / "pyproject.toml").exists(): + return candidate + raise RuntimeError("Could not find project root containing pyproject.toml") + + +def load_close(raw_dir: Path, symbol: str, alias: str | None = None) -> pd.DataFrame: + alias = alias or symbol + path = raw_dir / f"{symbol}.parquet" + if not path.exists(): + raise FileNotFoundError(f"Missing raw data file: {path}") + + frame = pd.read_parquet(path) + if "date" in frame.columns: + frame = frame.set_index("date") + if "close" not in frame.columns: + raise ValueError(f"{path} does not contain a close column") + + frame = frame.copy() + frame.index = pd.to_datetime(frame.index) + frame.index.name = "date" + frame = frame.sort_index() + return frame[["close"]].rename(columns={"close": f"{alias}_close"}) + + +def assign_chronological_splits(frame: pd.DataFrame, train_fraction: float, validation_fraction: float, test_fraction: float) -> pd.Series: + total_fraction = train_fraction + validation_fraction + test_fraction + if not np.isclose(total_fraction, 1.0): + raise ValueError(f"Split fractions must sum to 1.0, got {total_fraction}") + + n_rows = len(frame) + train_end = int(n_rows * train_fraction) + validation_end = train_end + int(n_rows * validation_fraction) + + split = pd.Series(index=frame.index, dtype="object") + split.iloc[:train_end] = "train" + split.iloc[train_end:validation_end] = "validation" + split.iloc[validation_end:] = "test" + return split + + +def build_dataset(raw_data_dir: Path, output_path: Path, symbols: dict, fractions: dict) -> pd.DataFrame: + prices = pd.concat( + [ + load_close(raw_data_dir, symbols["SPY"], "SPY"), + load_close(raw_data_dir, symbols["VIX"] , "VIX"), + load_close(raw_data_dir, symbols["TLT"] , "TLT"), + load_close(raw_data_dir, symbols["USO"] , "USO"), + ], + axis=1, + join="inner", + ) + + df = prices.copy() + df["SPY_ret_5"] = df["SPY_close"].pct_change(5) + df["SPY_ret_20"] = df["SPY_close"].pct_change(20) + + sma_50 = df["SPY_close"].rolling(50).mean() + df["SPY_dist_sma50"] = (df["SPY_close"] - sma_50) / sma_50 + + df["VIX_change_5"] = df["VIX_close"].pct_change(5) + df["VIX_rank_20"] = df["VIX_close"].rolling(20).rank(pct=True) + + df["TLT_ret_10"] = df["TLT_close"].pct_change(10) + df["USO_ret_5"] = df["USO_close"].pct_change(5) + df["SPY_TLT_ratio_ret"] = (df["SPY_close"] / df["TLT_close"]).pct_change(5) + + spy_forward_close = df["SPY_close"].shift(-5) + df["spy_up_5d"] = np.nan + df.loc[spy_forward_close > df["SPY_close"], "spy_up_5d"] = 1.0 + df.loc[spy_forward_close < df["SPY_close"], "spy_up_5d"] = 0.0 + df.loc[spy_forward_close == df["SPY_close"], "spy_up_5d"] = 0.5 + + FEATURE_COLUMNS = [ + "SPY_ret_5", + "SPY_ret_20", + "SPY_dist_sma50", + "VIX_change_5", + "VIX_rank_20", + "TLT_ret_10", + "USO_ret_5", + "SPY_TLT_ratio_ret", + ] + TARGET_COLUMN = "spy_up_5d" + + df_model = df[FEATURE_COLUMNS + [TARGET_COLUMN]].dropna().copy() + + # Drop unchanged targets (0.5) to keep binary classification + df_model = df_model[df_model[TARGET_COLUMN] != 0.5].copy() + df_model[TARGET_COLUMN] = df_model[TARGET_COLUMN].astype(int) + + df_model["split"] = assign_chronological_splits( + df_model, + fractions["train"], + fractions["validation"], + fractions["test"], + ) + + output_path.parent.mkdir(parents=True, exist_ok=True) + dataset_to_save = df_model.reset_index() + dataset_to_save.to_parquet(output_path, index=False) + + return df_model, FEATURE_COLUMNS, TARGET_COLUMN + + +def train_model(df_model: pd.DataFrame, feature_cols: list, target_col: str, config: dict, models_dir: Path): + train_df = df_model[df_model["split"] == "train"] + val_df = df_model[df_model["split"] == "validation"] + test_df = df_model[df_model["split"] == "test"] + + X_train, y_train = train_df[feature_cols], train_df[target_col] + X_val, y_val = val_df[feature_cols], val_df[target_col] + X_test, y_test = test_df[feature_cols], test_df[target_col] + + clf_params = dict(config) + # Ensure early_stopping_rounds present as int + + model = xgb.XGBClassifier(**clf_params) + + eval_set = [(X_train, y_train), (X_val, y_val)] + fit_kwargs = {"eval_set": eval_set, "verbose": False} + + model.fit(X_train, y_train, **fit_kwargs) + + print(f"Best iteration: {getattr(model, 'best_iteration', None)}") + evals = model.evals_result() + if "validation_1" in evals and "logloss" in evals["validation_1"]: + val_loss = evals["validation_1"]["logloss"] + print(f"Starting Validation Loss: {val_loss[0]:.4f}") + print(f"Final Validation Loss: {val_loss[-1]:.4f}") + + # Evaluate on test set + y_pred = model.predict(X_test) + print("\n--- Final Holdout Test Performance ---") + print(f"Test Set Accuracy: {accuracy_score(y_test, y_pred):.2%}\n") + print(classification_report(y_test, y_pred)) + + # Save model and metadata + models_dir.mkdir(parents=True, exist_ok=True) + model_path = models_dir / "spy_xgb_v1.json" + meta_path = models_dir / "spy_xgb_v1_meta.json" + model.save_model(str(model_path)) + + metadata = { + "p_base": float(y_train.mean()), + "feature_cols": feature_cols, + "last_trained_date": str(df_model.index.max().date()), + "config": config, + } + with open(meta_path, "w") as f: + json.dump(metadata, f, indent=2) + + print(f"Saved model to {model_path}") + + +def main(): + project_root = find_project_root() + + # Defaults + raw_data_dir = project_root / "data" / "alpaca" / "daily" + output_path = project_root / "data" / "training" / "spy_direction_5d.parquet" + models_dir = project_root / "models" + config_path = project_root / "config" / "train_config.json" + + # Load config + if not config_path.exists(): + raise FileNotFoundError(f"Config file not found: {config_path}") + with open(config_path, "r") as f: + config = json.load(f) + + symbols = config.get("symbols", {"SPY": "SPY", "VIX": config.get("vix_symbol", "VIXY"), "TLT": "TLT", "USO": "USO"}) + fractions = config.get("fractions", {"train": 0.7, "validation": 0.15, "test": 0.15}) + + print("Building dataset...") + df_model, feature_cols, target_col = build_dataset(raw_data_dir, output_path, symbols, fractions) + + print(f"Rows: {len(df_model):,}") + print(f"Feature columns: {feature_cols}") + print(f"Target column: {target_col}") + + split_counts = df_model.groupby("split").size() + print("Split counts:") + print(split_counts.to_string()) + + print("\nTraining model...") + model_config = config.get("model", {}) + train_model(df_model, feature_cols, target_col, model_config, models_dir) + + +if __name__ == "__main__": + main() diff --git a/src/trading_bot/models/prediction.py b/src/trading_bot/models/prediction.py index b857ec9..2541080 100644 --- a/src/trading_bot/models/prediction.py +++ b/src/trading_bot/models/prediction.py @@ -21,6 +21,8 @@ import pandas as pd import xgboost as xgb from dotenv import load_dotenv +from trading_bot.data.alpaca_daily_lib import refresh_recent_market_data + # Load environment variables from .env file if available load_dotenv() @@ -158,9 +160,20 @@ def predict_latest_probability( raw_data_dir: Path | str, symbols: dict[str, str] | None = None, max_age_days: int = 1, + api_key: str | None = None, + secret_key: str | None = None, + fetch_recent_data: bool = False, ) -> PredictionResult: """Return the latest predicted probability for the next SPY move.""" + if fetch_recent_data: + refresh_recent_market_data( + output_dir=raw_data_dir, + symbols=symbols or DEFAULT_SYMBOLS, + api_key=api_key, + secret_key=secret_key, + ) + model = load_model(model_path) metadata = load_feature_metadata(metadata_path) latest_date, latest_features = get_latest_inference_features( @@ -249,6 +262,9 @@ def main() -> None: model_path=args.model_path, metadata_path=args.metadata_path, raw_data_dir=args.data_dir, + api_key=args.api_key, + secret_key=args.secret_key, + fetch_recent_data=True, ) print( f"Date: {result.prediction_date.date()} | Prob: {result.probability:.4f} | " diff --git a/tests/test_prediction.py b/tests/test_prediction.py index 3969a75..0b41656 100644 --- a/tests/test_prediction.py +++ b/tests/test_prediction.py @@ -1,8 +1,72 @@ from pathlib import Path +import numpy as np +import pandas as pd + from trading_bot.models.prediction import FEATURE_COLUMNS, predict_latest_probability +class FakeModel: + def predict_proba(self, model_input): + return np.array([[0.1, 0.9]]) + + +def test_predict_latest_probability_refreshes_recent_market_data( + monkeypatch, +) -> None: + refresh_calls: dict[str, object] = {} + + def fake_refresh_recent_data( + output_dir: Path, + symbols: dict[str, str] | None = None, + api_key: str | None = None, + secret_key: str | None = None, + ) -> None: + refresh_calls["symbols"] = list((symbols or {}).keys()) + refresh_calls["output_dir"] = output_dir + refresh_calls["api_key"] = api_key + refresh_calls["secret_key"] = secret_key + + monkeypatch.setattr( + "trading_bot.models.prediction.refresh_recent_market_data", + fake_refresh_recent_data, + ) + monkeypatch.setattr( + "trading_bot.models.prediction.load_model", + lambda model_path: FakeModel(), + ) + monkeypatch.setattr( + "trading_bot.models.prediction.load_feature_metadata", + lambda metadata_path: {"feature_cols": FEATURE_COLUMNS, "p_base": 0.5}, + ) + monkeypatch.setattr( + "trading_bot.models.prediction.get_latest_inference_features", + lambda raw_data_dir, symbols=None, max_age_days=1: ( + pd.Timestamp("2026-08-03"), + pd.DataFrame( + [[0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08]], + columns=FEATURE_COLUMNS, + index=[pd.Timestamp("2026-08-03")], + ), + ), + ) + + result = predict_latest_probability( + model_path=Path("notebooks/models/spy_xgb_v1.json"), + metadata_path=Path("notebooks/models/spy_xgb_v1_meta.json"), + raw_data_dir=Path("data/alpaca/daily"), + api_key="test-key", + secret_key="test-secret", + fetch_recent_data=True, + ) + + assert refresh_calls["output_dir"] == Path("data/alpaca/daily") + assert refresh_calls["symbols"] == ["SPY", "VIXY", "TLT", "USO"] + assert refresh_calls["api_key"] == "test-key" + assert refresh_calls["secret_key"] == "test-secret" + assert result.probability == 0.9 + + def test_predict_latest_probability_returns_probability_between_zero_and_one() -> None: result = predict_latest_probability( model_path=Path("notebooks/models/spy_xgb_v1.json"),