> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quantspace.limex.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# run_ml_job

> Train classical ML models (sklearn, XGBoost, LightGBM, CatBoost) for return forecasts

## Overview

`run_ml_job` trains a classical machine learning model on feature-engineered data and produces per-ticker **next-day log-return** predictions for the ML-enhanced portfolio path.

Supported libraries:

* **scikit-learn** — linear, ridge, lasso, elastic net, quantile, random forest, …
* **XGBoost**, **LightGBM**, **CatBoost** — gradient-boosting regressors

This stage is **optional**. The default QuantLab path is data → PO → trading. Use ML when you want predicted returns as μ (`mu_mode: custom` in `run_po_job`).

<Note>
  For XGBoost, LightGBM, and CatBoost, QuantLab uses the **regressor** APIs (e.g. `XGBRegressor`, `LGBMRegressor`, `CatBoostRegressor`) to predict continuous returns — not classifiers or clustering.
</Note>

***

## Hyperparameters — full library power

Pass any constructor argument the chosen model accepts via `model_params`. The worker forwards those kwargs into the library’s estimator `__init__`, so you can use the full API surface of sklearn / XGBoost / LightGBM / CatBoost (learning rate, depth, subsample, `reg_alpha`, `l1_ratio`, `random_state`, and so on).

Examples:

```json theme={null}
"model": "xgboost",
"model_params": {
  "n_estimators": 300,
  "max_depth": 5,
  "learning_rate": 0.05,
  "subsample": 0.8,
  "colsample_bytree": 0.8,
  "random_state": 42
}
```

```json theme={null}
"model": "lightgbm",
"model_params": {
  "n_estimators": 400,
  "num_leaves": 63,
  "learning_rate": 0.03,
  "min_child_samples": 20
}
```

```json theme={null}
"model": "catboost",
"model_params": {
  "iterations": 500,
  "depth": 6,
  "learning_rate": 0.05,
  "random_seed": 42
}
```

In chat you can just say “XGBoost with max\_depth 5 and 300 trees” — MCP skills fill in `model_params`.

***

## Parameters

<ParamField body="feature_url" type="string" required>
  URL of `feature_engine_*.json` from `run_feature_worker`.
</ParamField>

<ParamField body="data_extractor_url" type="string" required>
  URL of `data_extractor_*.json` from `run_data_extraction` (train/test date alignment).
</ParamField>

<ParamField body="config" type="object" required>
  ML configuration.

  <Expandable title="config fields">
    <ParamField body="ML params" type="object" required>
      <Expandable title="ML params fields">
        <ParamField body="model" type="string" required>
          Model key (case-insensitive):

          | Value                              | Backend                                |
          | ---------------------------------- | -------------------------------------- |
          | `"random_forest"` / `"rf"`         | scikit-learn RandomForest**Regressor** |
          | `"xgboost"` / `"xgb"`              | XGBoost **regressor**                  |
          | `"lightgbm"` / `"lgbm"`            | LightGBM **regressor**                 |
          | `"catboost"`                       | CatBoost **regressor**                 |
          | `"linear"` / `"linear_regression"` | sklearn LinearRegression               |
          | `"ridge"`                          | sklearn Ridge                          |
          | `"lasso"`                          | sklearn Lasso                          |
          | `"elastic_net"`                    | sklearn ElasticNet                     |
          | `"quantile"`                       | sklearn QuantileRegressor              |

          Unknown names raise an error (no silent fallback).
        </ParamField>

        <ParamField body="model_params" type="object">
          Dict of hyperparameters for the model constructor — any kwargs supported by that library’s regressor API.
        </ParamField>

        <ParamField body="cv_test_size" type="integer">
          Samples per CV test fold (walk-forward). Default: `15`. Legacy alias: `test_size`.
        </ParamField>

        <ParamField body="n_splits" type="integer">
          Number of CV splits. Default: `15`.
        </ParamField>

        <ParamField body="intervals" type="object">
          Optional MAPIE conformal intervals (`enabled`, `alpha`, `bound`).
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

***

## Returns

```json theme={null}
{
  "status": "Succeeded",
  "output_url": "https://stqsnpprod.blob.core.windows.net/data/ml_engine_7d4e2a91c0bf.json",
  "output_name": "ml_engine_7d4e2a91c0bf.json",
  "execution_name": "ml-worker-job-abc123xyz"
}
```

Pass `output_url` to [`run_po_job`](/tools/po-job). Prefer [`run_dl_job`](/tools/dl-job) if you want neural nets instead.

***

## Example

```json theme={null}
{
  "feature_url": "https://stqsnpprod.blob.core.windows.net/data/feature_engine_a1c3e5f70912.json",
  "data_extractor_url": "https://stqsnpprod.blob.core.windows.net/data/data_extractor_2b510101b9b7.json",
  "config": {
    "ML params": {
      "model": "xgboost",
      "model_params": {
        "n_estimators": 200,
        "max_depth": 4,
        "learning_rate": 0.05,
        "random_state": 42
      },
      "cv_test_size": 15,
      "n_splits": 15,
      "intervals": {
        "enabled": false,
        "alpha": 0.99,
        "bound": "center"
      }
    }
  }
}
```

***

## Resources

| Resource           | Value                                         |
| ------------------ | --------------------------------------------- |
| Container Apps Job | `ml-worker-job`                               |
| Env vars injected  | `FEATURE_URL`, `DATA_EXTRACTOR_URL`, `CONFIG` |
| Output blob prefix | `ml_engine_`                                  |
